<template>
  <div class="dashboard-container">
    <!-- 顶部工具栏 - 增强版 -->
    <div class="top-toolbar">
      <div class="toolbar-left">
        <h2 class="page-title">
          <el-icon class="title-icon"><Lock /></el-icon>
          <span class="title-text">系统概览</span>
        </h2>
        <div class="date-range">
          <el-date-picker
            v-model="dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :shortcuts="dateRangeShortcuts"
            @change="handleDateRangeChange"
            class="date-picker"
            popper-class="date-picker-popper"
          />
        </div>
      </div>
      <div class="toolbar-right">
        <!-- 通知中心 -->
        <div class="notification-wrapper">
          <el-dropdown trigger="click" @command="handleNotificationCommand" class="notification-dropdown">
            <el-button class="notification-btn"
              :class="{ 'has-notifications': unreadNotifications > 0 }"
              circle
              type="default"
              size="small"
              :loading="isLoadingNotifications"
            >
              <el-icon><Bell /></el-icon>
              <el-badge 
                v-if="unreadNotifications > 0" 
                :value="unreadNotifications" 
                :max="99" 
                class="notification-badge"
                type="danger"
              />
            </el-button>
            <template #dropdown>
              <div class="notification-panel">
                <div class="notification-header">
                  <h3>通知中心</h3>
                  <el-button v-if="unreadNotifications > 0" type="text" size="small" class="mark-all-read">全部已读</el-button>
                </div>
                <div class="notification-list">
                  <div v-for="(item, index) in mockNotifications" :key="index" class="notification-item">
                    <el-avatar :size="36" :icon="item.icon" :class="`notification-avatar ${item.type}`" />
                    <div class="notification-content">
                      <div class="notification-title">{{ item.title }}</div>
                      <div class="notification-desc">{{ item.description }}</div>
                      <div class="notification-time">{{ item.time }}</div>
                    </div>
                    <el-tag v-if="item.unread" type="danger" size="small" class="unread-tag">新</el-tag>
                  </div>
                </div>
                <div class="notification-footer">
                  <el-button type="text" size="small" class="view-all-notifications">查看所有通知</el-button>
                </div>
              </div>
            </template>
          </el-dropdown>
        </div>
        
        <!-- 视图模式切换 -->
        <el-dropdown @command="handleViewModeChange" class="view-mode-selector">
          <el-button type="text" class="mode-btn">
            <el-icon><View /></el-icon>
            {{ currentViewMode === 'card' ? '卡片视图' : '列表视图' }}
            <el-icon class="el-icon--right"><CaretBottom /></el-icon>
          </el-button>
          <template #dropdown>
            <el-dropdown-menu class="dropdown-menu-enhanced">
              <el-dropdown-item command="card">
                <el-icon class="dropdown-icon"><Grid /></el-icon>
                <span>卡片视图</span>
              </el-dropdown-item>
              <el-dropdown-item command="list">
                <el-icon class="dropdown-icon"><List /></el-icon>
                <span>列表视图</span>
              </el-dropdown-item>
              <el-dropdown-item command="compact">
                <el-icon class="dropdown-icon"><Shrink /></el-icon>
                <span>紧凑视图</span>
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        
        <!-- 高级数据过滤 -->
        <el-dropdown @command="handleFilterChange" class="filter-selector">
          <el-button type="text" class="mode-btn">
            <el-icon><Filter /></el-icon>
            数据过滤
            <el-icon class="el-icon--right"><CaretBottom /></el-icon>
          </el-button>
          <template #dropdown>
            <el-dropdown-menu class="dropdown-menu-enhanced">
              <el-dropdown-item command="all">
                <el-icon class="dropdown-icon"><Filter /></el-icon>
                <span>全部数据</span>
              </el-dropdown-item>
              <el-dropdown-item command="highRiskOnly">
                <el-icon class="dropdown-icon"><Warning /></el-icon>
                <span>仅高危漏洞</span>
              </el-dropdown-item>
              <el-dropdown-item command="recentOnly">
                <el-icon class="dropdown-icon"><Timer /></el-icon>
                <span>最近30天</span>
              </el-dropdown-item>
              <el-dropdown-item command="custom">
                <el-icon class="dropdown-icon"><Setting /></el-icon>
                <span>自定义过滤...</span>
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        
        <!-- 数据导出 -->
        <el-dropdown @command="handleExport" class="export-selector">
          <el-button type="text" class="mode-btn">
            <el-icon><Download /></el-icon>
            导出数据
            <el-icon class="el-icon--right"><CaretBottom /></el-icon>
          </el-button>
          <template #dropdown>
            <el-dropdown-menu class="dropdown-menu-enhanced">
              <el-dropdown-item command="pdf">
                <el-icon class="dropdown-icon"><Document /></el-icon>
                <span>PDF报告</span>
              </el-dropdown-item>
              <el-dropdown-item command="excel">
                <el-icon class="dropdown-icon"><DataAnalysis /></el-icon>
                <span>Excel表格</span>
              </el-dropdown-item>
              <el-dropdown-item command="json">
                <el-icon class="dropdown-icon"><Code /></el-icon>
                <span>JSON数据</span>
              </el-dropdown-item>
              <el-dropdown-item command="charts">
                <el-icon class="dropdown-icon"><Histogram /></el-icon>
                <span>导出图表</span>
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        
        <!-- 自动刷新控制 -->
        <el-button 
          :type="autoRefreshEnabled ? 'success' : 'default'" 
          @click="toggleAutoRefresh"
          size="small"
          class="auto-refresh-btn"
          :class="{ 'refresh-active': autoRefreshEnabled }"
        >
          <el-icon class="refresh-icon" :class="{ 'rotating': autoRefreshEnabled }"><Refresh /></el-icon>
          {{ autoRefreshEnabled ? '自动刷新中' : '启用自动刷新' }}
        </el-button>
        
        <!-- 手动刷新 -->
        <el-button @click="refreshDashboard" :loading="isRefreshing" class="refresh-btn" size="small">
          <el-icon><Refresh /></el-icon>
          刷新数据
        </el-button>
        
        <!-- 新建扫描 -->
        <el-button type="primary" @click="goToScanPage" class="primary-action scan-btn">
          <el-icon><Search /></el-icon>
          <span>新建扫描</span>
        </el-button>
      </div>
    </div>

    <!-- 系统状态指示器 - 增强版 -->
    <div class="system-status-bar">
      <!-- 系统健康状态 -->
      <div class="status-item">
        <span class="status-label">系统状态:</span>
        <div class="status-indicator-wrapper">
          <el-tooltip :content="getSystemHealthDetails" placement="top" effect="dark">
            <span class="status-indicator" :class="systemStatus" :style="{ backgroundColor: getStatusBackgroundColor }">
              <el-icon :class="`status-icon ${getSystemStatusIcon}`"></el-icon>
              {{ systemStatusText }}
            </span>
          </el-tooltip>
          <el-badge 
            v-if="pendingTasks > 0"
            :value="pendingTasks" 
            :max="99" 
            class="pending-badge"
            type="warning"
          >
          </el-badge>
        </div>
      </div>
      
      <!-- 上次更新时间 -->
      <div class="status-item">
        <span class="status-label">上次更新:</span>
        <span class="last-update" :class="{'recent-update': isRecentlyUpdated}">
          {{ lastUpdatedTime }}
          <el-tooltip content="相对时间" placement="top" effect="dark">
            <span class="relative-time">({{ getRelativeTime(lastUpdated) }})</span>
          </el-tooltip>
        </span>
      </div>
      
      <!-- 扫描器状态 -->
      <div class="status-item">
        <span class="status-label">扫描器状态:</span>
        <div class="scanner-status">
          <div class="scanner-progress-container">
            <el-progress 
              :percentage="scannerHealthPercentage" 
              :stroke-width="6" 
              :show-text="false" 
              :color="scannerHealthColor"
              class="scanner-progress"
            ></el-progress>
          </div>
          <span class="scanner-count" :class="getScannerStatusClass">
            {{ activeScanners }}/{{ totalScanners }}
          </span>
        </div>
      </div>
      
      <!-- 系统负载 -->
      <div class="status-item">
        <span class="status-label">系统负载:</span>
        <div class="load-info">
          <div class="load-progress-container">
            <el-progress 
              :percentage="systemLoad" 
              :stroke-width="6" 
              :show-text="false" 
              :color="getLoadColor(systemLoad)"
              class="system-load"
            ></el-progress>
          </div>
          <span class="load-text" :class="getLoadTextClass(systemLoad)">{{ systemLoad }}%</span>
        </div>
      </div>
      
      <!-- 资源使用 -->
      <div class="status-item">
        <span class="status-label">资源使用:</span>
        <div class="resource-usage">
          <el-tooltip content="CPU使用率" placement="top" effect="dark">
            <span class="resource-item" :class="getResourceClass(cpuUsage)">
              <el-icon><Cpu /></el-icon>
              {{ cpuUsage }}%
            </span>
          </el-tooltip>
          <el-tooltip content="内存使用率" placement="top" effect="dark">
            <span class="resource-item" :class="getResourceClass(memoryUsage)">
              <el-icon><DataLine /></el-icon>
              {{ memoryUsage }}%
            </span>
          </el-tooltip>
          <el-tooltip content="磁盘使用率" placement="top" effect="dark">
            <span class="resource-item" :class="getResourceClass(diskUsage)">
              <el-icon><Folder /></el-icon>
              {{ diskUsage }}%
            </span>
          </el-tooltip>
        </div>
      </div>
      
      <!-- 快速操作 -->
      <div class="status-item actions">
        <el-button 
          type="primary" 
          size="small" 
          @click="runHealthCheck"
          :loading="isCheckingServices"
          class="health-check-btn"
          plain
        >
          <el-icon><Refresh /></el-icon>
          健康检查
        </el-button>
        <el-button 
          type="default" 
          size="small" 
          @click="viewSystemLogs"
          class="logs-btn"
          plain
        >
          <el-icon><Document /></el-icon>
          系统日志
        </el-button>
      </div>
    </div>

    <!-- 安全态势概览卡片 -->
    <div class="security-overview-card">
      <el-card class="overview-card" shadow="hover" body-style="padding: 0">
        <div class="overview-header">
          <div class="overview-title">
            <el-icon class="overview-icon"><Lock /></el-icon>
            <h3>安全态势概览</h3>
          </div>
          <el-select v-model="overviewTimeRange" size="small" class="overview-range-select">
            <el-option label="今日" value="today" />
            <el-option label="本周" value="week" />
            <el-option label="本月" value="month" />
            <el-option label="本季度" value="quarter" />
          </el-select>
        </div>
        <div class="overview-content">
          <div class="overview-metrics">
            <div class="overview-metric">
              <div class="metric-value">{{ todayScans }}</div>
              <div class="metric-label">今日扫描</div>
              <div class="metric-change" :class="todayScansChange > 0 ? 'positive' : 'negative'">
                  <el-icon v-if="todayScansChange !== 0">
                    <CaretTop v-if="todayScansChange > 0" />
                    <CaretBottom v-else />
                  </el-icon>
                  {{ Math.abs(todayScansChange) }}%
                </div>
            </div>
            <div class="overview-metric">
              <div class="metric-value">{{ todayVulnerabilities }}</div>
              <div class="metric-label">今日漏洞</div>
              <div class="metric-change" :class="todayVulnerabilitiesChange > 0 ? 'negative' : 'positive'">
                  <el-icon v-if="todayVulnerabilitiesChange !== 0">
                    <CaretTop v-if="todayVulnerabilitiesChange > 0" />
                    <CaretBottom v-else />
                  </el-icon>
                  {{ Math.abs(todayVulnerabilitiesChange) }}%
                </div>
            </div>
            <div class="overview-metric">
              <div class="metric-value">{{ criticalVulnerabilities }}</div>
              <div class="metric-label">高危漏洞</div>
              <div class="metric-change" :class="criticalVulnerabilitiesChange > 0 ? 'negative' : 'positive'">
                  <el-icon v-if="criticalVulnerabilitiesChange !== 0">
                    <CaretTop v-if="criticalVulnerabilitiesChange > 0" />
                    <CaretBottom v-else />
                  </el-icon>
                  {{ Math.abs(criticalVulnerabilitiesChange) }}%
                </div>
            </div>
            <div class="overview-metric">
              <div class="metric-value">{{ avgRemediationTime }}h</div>
              <div class="metric-label">平均修复时间</div>
              <div class="metric-change" :class="avgRemediationTimeChange > 0 ? 'negative' : 'positive'">
                  <el-icon v-if="avgRemediationTimeChange !== 0">
                    <CaretTop v-if="avgRemediationTimeChange > 0" />
                    <CaretBottom v-else />
                  </el-icon>
                  {{ Math.abs(avgRemediationTimeChange) }}%
                </div>
            </div>
          </div>
          <div class="overview-trend-chart" ref="overviewTrendChartRef"></div>
        </div>
      </el-card>
    </div>
    
    <!-- 关键指标卡片 - 使用网格布局和高级样式 -->
    <div class="metrics-grid">
      <!-- 总扫描任务卡片 -->
      <el-card class="metric-card overflow-hidden transition-all duration-300 hover:shadow-lg hover:translate-y-[-4px]" shadow="hover" :body-style="{ padding: '0' }">
        <div class="relative">
          <!-- 装饰性背景元素 -->
          <div class="metric-bg-decoration success-bg"></div>
          <!-- 卡片内容 -->
          <div class="metric-content p-5">
            <div class="metric-header flex items-center justify-between">
              <div class="metric-icon-container success flex items-center justify-center w-12 h-12 rounded-full shadow-md transition-all duration-300 hover:scale-110">
                <el-icon class="icon-scan text-xl"><Search /></el-icon>
              </div>
              <el-dropdown @command="handleMetricCardAction" class="metric-action-dropdown">
                <el-button size="small" type="text" class="metric-action">
                  <el-icon><More /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item command="viewDetails">查看详情</el-dropdown-item>
                    <el-dropdown-item command="exportData">导出数据</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
            <div class="metric-info mt-4">
              <h3 class="metric-title text-sm font-medium text-gray-600 tracking-wide">总扫描任务</h3>
              <div class="metric-value text-3xl font-bold mt-1">{{ totalScans.toLocaleString() }}</div>
              <div class="metric-stats flex items-center mt-2 space-x-4">
                <span class="metric-change text-sm font-medium" :class="scansChange > 0 ? 'text-success' : 'text-danger'">
                    <el-icon v-if="scansChange > 0" class="inline-block mr-1"><CaretTop /></el-icon>
                    <el-icon v-else class="inline-block mr-1"><CaretBottom /></el-icon>
                    {{ Math.abs(scansChange) }}% 较昨日
                  </span>
                <span class="metric-rate text-xs text-gray-500 bg-gray-100 px-2 py-1 rounded-full">{{ scansPerHour }}/小时</span>
              </div>
            </div>
          </div>
          <!-- 底部渐变装饰 -->
          <div class="metric-footer-gradient success-gradient"></div>
          <!-- 装饰性元素 -->
          <div class="metric-decoration"></div>
        </div>
      </el-card>

      <!-- 发现漏洞卡片 -->
      <el-card class="metric-card overflow-hidden transition-all duration-300 hover:shadow-lg hover:translate-y-[-4px]" shadow="hover" :body-style="{ padding: '0' }">
        <div class="relative">
          <!-- 装饰性背景元素 -->
          <div class="metric-bg-decoration warning-bg"></div>
          <!-- 卡片内容 -->
          <div class="metric-content p-5">
            <div class="metric-header flex items-center justify-between">
              <div class="metric-icon-container warning flex items-center justify-center w-12 h-12 rounded-full shadow-md transition-all duration-300 hover:scale-110">
                <el-icon class="icon-vuln text-xl"><Warning /></el-icon>
              </div>
              <el-dropdown @command="handleMetricCardAction" class="metric-action-dropdown">
                <el-button size="small" type="text" class="metric-action">
                  <el-icon><More /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item command="viewDetails">查看详情</el-dropdown-item>
                    <el-dropdown-item command="exportData">导出数据</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
            <div class="metric-info mt-4">
              <h3 class="metric-title text-sm font-medium text-gray-600 tracking-wide">发现漏洞</h3>
              <div class="metric-value text-3xl font-bold mt-1">{{ totalVulnerabilities.toLocaleString() }}</div>
              <div class="metric-stats flex items-center mt-2 space-x-4">
                <span class="metric-change text-sm font-medium" :class="vulnsChange > 0 ? 'text-warning' : 'text-success'">
                  <el-icon v-if="vulnsChange > 0" class="inline-block mr-1"><CaretTop /></el-icon>
                  <el-icon v-else class="inline-block mr-1"><CaretBottom /></el-icon>
                  {{ Math.abs(vulnsChange) }}% 较昨日
                </span>
                <span class="metric-rate text-xs text-gray-500 bg-gray-100 px-2 py-1 rounded-full">{{ vulnsPerScan }}/扫描</span>
              </div>
            </div>
          </div>
          <!-- 底部渐变装饰 -->
          <div class="metric-footer-gradient warning-gradient"></div>
          <div class="metric-decoration"></div>
        </div>
      </el-card>

      <!-- 高风险漏洞卡片 -->
      <el-card class="metric-card overflow-hidden transition-all duration-300 hover:shadow-lg hover:translate-y-[-4px]" shadow="hover" :body-style="{ padding: '0' }">
        <div class="relative">
          <!-- 装饰性背景元素 -->
          <div class="metric-bg-decoration danger-bg"></div>
          <!-- 卡片内容 -->
          <div class="metric-content p-5">
            <div class="metric-header flex items-center justify-between">
              <div class="metric-icon-container danger flex items-center justify-center w-12 h-12 rounded-full shadow-md transition-all duration-300 hover:scale-110">
                <el-icon class="icon-risk text-xl"><Fire /></el-icon>
              </div>
              <el-dropdown @command="handleMetricCardAction" class="metric-action-dropdown">
                <el-button size="small" type="text" class="metric-action">
                  <el-icon><More /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item command="viewDetails">查看详情</el-dropdown-item>
                    <el-dropdown-item command="exportData">导出数据</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
            <div class="metric-info mt-4">
              <h3 class="metric-title text-sm font-medium text-gray-600 tracking-wide">高风险漏洞</h3>
              <div class="metric-value text-3xl font-bold mt-1">{{ highRiskVulnerabilities.toLocaleString() }}</div>
              <div class="metric-stats flex items-center mt-2 space-x-4">
                <span class="metric-change text-sm font-medium" :class="highRiskChange > 0 ? 'text-danger' : 'text-success'">
                  {{ highRiskChange > 0 ? '↑' : '↓' }} {{ Math.abs(highRiskChange) }}% 较昨日
                </span>
                <span class="metric-percentage text-xs font-semibold text-danger bg-red-50 px-2 py-1 rounded-full">
                  {{ highRiskPercentage }}% 占比
                </span>
              </div>
            </div>
          </div>
          <!-- 底部渐变装饰 -->
          <div class="metric-footer-gradient danger-gradient"></div>
          <div class="metric-decoration"></div>
        </div>
      </el-card>

      <!-- 安全评分卡片 -->
      <el-card class="metric-card overflow-hidden transition-all duration-300 hover:shadow-lg hover:translate-y-[-4px]" shadow="hover" :body-style="{ padding: '0' }">
        <div class="relative">
          <!-- 装饰性背景元素 -->
          <div class="metric-bg-decoration info-bg"></div>
          <!-- 卡片内容 -->
          <div class="metric-content p-5">
            <div class="metric-header flex items-center justify-between">
              <div class="metric-icon-container info flex items-center justify-center w-12 h-12 rounded-full shadow-md transition-all duration-300 hover:scale-110">
                <el-icon class="icon-security text-xl"><Lock /></el-icon>
              </div>
              <el-dropdown @command="handleMetricCardAction" class="metric-action-dropdown">
                <el-button size="small" type="text" class="metric-action">
                  <el-icon><More /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item command="viewDetails">查看详情</el-dropdown-item>
                    <el-dropdown-item command="exportData">导出数据</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
            <div class="metric-info mt-4">
              <h3 class="metric-title text-sm font-medium text-gray-600 tracking-wide">安全评分</h3>
              <p class="metric-value score-value text-3xl font-bold mt-1">{{ securityScore }}/100</p>
              
              <!-- 评分进度条 -->
              <div class="score-progress mt-2">
                <el-progress 
                  :percentage="securityScore" 
                  :color="getScoreColor(securityScore)"
                  :stroke-width="6"
                  :show-text="false"
                  class="score-progress-bar"
                />
              </div>
              
              <div class="metric-stats flex items-center mt-2 space-x-4">
                <span class="metric-change text-sm font-medium" :class="securityScoreChange > 0 ? 'text-success' : 'text-danger'">
                  <el-icon v-if="securityScoreChange > 0" class="inline-block mr-1"><CaretTop /></el-icon>
                  <el-icon v-else class="inline-block mr-1"><CaretBottom /></el-icon>
                  {{ Math.abs(securityScoreChange) }} 较昨日
                </span>
                <span class="metric-grade text-xs font-semibold px-2 py-1 rounded-full" :class="getGradeClass(securityGrade)">
                  {{ securityGrade }}
                </span>
              </div>
            </div>
          </div>
          <!-- 底部渐变装饰 -->
          <div class="metric-footer-gradient info-gradient"></div>
          <div class="metric-decoration"></div>
        </div>
      </el-card>
    </div>

    <!-- 趋势图表区域 - 增强版 -->
    <div class="charts-grid">
      <!-- 漏洞类型分布图表 -->
      <el-card class="chart-card" shadow="hover" v-loading="isChartsLoading" element-loading-text="加载图表数据...">
        <template #header>
          <div class="card-header">
            <el-icon><el-icon-DataAnalysis /></el-icon>
            <span class="header-title">漏洞类型分布</span>
            <div class="chart-actions">
              <!-- 图表类型切换 -->
              <el-select v-model="chartType1" size="small" @change="updateCharts" class="chart-type-select">
                <el-option label="饼图" value="pie"></el-option>
                <el-option label="柱状图" value="bar"></el-option>
                <el-option label="环形图" value="doughnut"></el-option>
              </el-select>
              
              <!-- 图表操作按钮组 -->
              <el-dropdown @command="handleChart1Action" class="chart-commands">
                <el-button size="small" type="text">
                  <el-icon><el-icon-More /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item command="export">导出图表</el-dropdown-item>
                    <el-dropdown-item command="print">打印图表</el-dropdown-item>
                    <el-dropdown-item command="refresh">刷新数据</el-dropdown-item>
                    <el-dropdown-item command="fullscreen">全屏查看</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
              
              <!-- 数据筛选 -->
              <el-popover
                placement="top-right"
                width="200"
                trigger="click"
                :visible="showChart1Filter"
                @visible-change="showChart1Filter = $event"
              >
                <template #reference>
                  <el-button size="small" type="text" class="filter-btn">
                    <el-icon><el-icon-Filter /></el-icon>
                  </el-button>
                </template>
                <div class="chart-filter-content">
                  <h4>漏洞等级筛选</h4>
                  <el-checkbox-group v-model="vulnerabilitySeverityFilters">
                    <el-checkbox label="high">高危</el-checkbox>
                    <el-checkbox label="medium">中危</el-checkbox>
                    <el-checkbox label="low">低危</el-checkbox>
                  </el-checkbox-group>
                  <el-button type="primary" size="small" @click="applyChart1Filter" class="filter-apply-btn">应用筛选</el-button>
                </div>
              </el-popover>
            </div>
          </div>
        </template>
        
        <!-- 图表内容区域 -->
        <div class="chart-container">
          <div class="chart-wrapper animated fadeIn" ref="vulnerabilityChartRef" style="height: 300px;">
            <!-- 漏洞分布图表 -->
          </div>
          
          <!-- 图表数据摘要 -->
          <div class="chart-summary card-shadow">
            <div class="summary-item" v-for="item in vulnerabilitySummaryData" :key="item.type">
              <div class="summary-icon" :class="item.severity"></div>
              <span class="summary-label">{{ item.label }}:</span>
              <span class="summary-value" :class="item.severity">{{ item.count }}</span>
              <span class="summary-percentage">({{ item.percentage }}%)</span>
              <div class="summary-trend" :class="getTrendClass(item.change)">
                <span v-if="item.change > 0">↑</span>
                <span v-else-if="item.change < 0">↓</span>
                <span v-else>-</span>
                <span>{{ Math.abs(item.change) }}%</span>
              </div>
            </div>
          </div>
        </div>
      </el-card>

      <!-- 扫描趋势图表 -->
      <el-card class="chart-card card-shadow-hover border-light" v-loading="isChartsLoading" element-loading-text="加载图表数据...">
        <template #header>
          <div class="card-header">
            <div class="header-left">
              <el-icon class="header-icon"><el-icon-LineChart /></el-icon>
              <span class="header-title">扫描趋势分析</span>
              <el-tag v-if="scanTrendData.length > 0" size="small" type="info" effect="plain" class="chart-data-count">
                共 {{ scanTrendData.dates?.length || 0 }} 天数据
              </el-tag>
            </div>
            <div class="chart-actions">
              <!-- 时间范围选择 -->
              <el-select v-model="scanTrendRange" size="small" @change="updateScanTrendChart" class="range-select rounded-full">
                <el-option label="近7天" value="7d"></el-option>
                <el-option label="近30天" value="30d"></el-option>
                <el-option label="近90天" value="90d"></el-option>
                <el-option label="自定义" value="custom"></el-option>
              </el-select>
              
              <!-- 图表类型切换 -->
              <el-radio-group v-model="chartType2" size="small" class="chart-type-select">
                <el-radio-button label="line" title="折线图">
                  <el-icon><el-icon-Line /></el-icon>
                </el-radio-button>
                <el-radio-button label="area" title="面积图">
                  <el-icon><el-icon-Picture /></el-icon>
                </el-radio-button>
              </el-radio-group>
              
              <!-- 图表操作按钮组 -->
              <el-dropdown @command="handleChart2Action" class="chart-commands">
                <el-button size="small" type="primary" plain circle>
                  <el-icon><el-icon-More /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item command="export" icon="el-icon-Download">导出图表</el-dropdown-item>
                    <el-dropdown-item command="print" icon="el-icon-Print">打印图表</el-dropdown-item>
                    <el-dropdown-item command="refresh" icon="el-icon-Refresh">刷新数据</el-dropdown-item>
                    <el-dropdown-item command="fullscreen" icon="el-icon-FullScreen">全屏查看</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
              
              <!-- 显示选项 -->
              <el-popover
                placement="top-right"
                width="240"
                trigger="click"
                :visible="showChart2Filter"
                @visible-change="showChart2Filter = $event"
              >
                <template #reference>
                  <el-button size="small" type="info" plain circle class="filter-btn">
                    <el-icon><el-icon-Setting /></el-icon>
                  </el-button>
                </template>
                <div class="chart-filter-content p-4 bg-card">
                  <h4 class="filter-title mb-3">显示选项</h4>
                  <el-checkbox-group v-model="chart2VisibleSeries">
                    <el-checkbox v-model="showScanCount" label="scanCount" class="filter-item">扫描次数</el-checkbox>
                    <el-checkbox v-model="showVulnerabilityCount" label="vulnerabilityCount" class="filter-item">漏洞数量</el-checkbox>
                    <el-checkbox v-model="showSuccessRate" label="successRate" class="filter-item">成功率</el-checkbox>
                  </el-checkbox-group>
                  <div class="filter-footer mt-4">
                    <el-button type="default" size="small" @click="resetChart2Filter" class="mr-2">重置</el-button>
                    <el-button type="primary" size="small" @click="applyChart2Filter">应用设置</el-button>
                  </div>
                </div>
              </el-popover>
            </div>
          </div>
        </template>
        
        <!-- 图表内容区域 -->
        <div class="chart-container">
          <div class="chart-wrapper animated fadeIn" ref="scanTrendChartRef" style="height: 300px;">
            <!-- 扫描趋势图表将在这里渲染 -->
          </div>
          
          <!-- 图表数据摘要 -->
          <div class="chart-summary card-shadow grid grid-cols-3 gap-4 mt-4">
            <div class="summary-card bg-primary/10 rounded-lg p-3">
              <div class="summary-label text-primary text-sm">平均每天扫描</div>
              <div class="summary-value text-2xl font-bold text-primary">{{ avgDailyScans }}</div>
              <div class="summary-detail text-xs text-gray-500">近 {{ scanTrendData.dates?.length || 0 }} 天平均值</div>
            </div>
            <div class="summary-card bg-success/10 rounded-lg p-3">
              <div class="summary-label text-success text-sm">最高扫描日</div>
              <div class="summary-value text-2xl font-bold text-success">{{ highestScanDay }}</div>
              <div class="summary-detail text-xs text-gray-500">{{ getHighestScanCount() }} 次扫描</div>
            </div>
            <div class="summary-card bg-warning/10 rounded-lg p-3">
              <div class="summary-label text-warning text-sm">成功率</div>
              <div class="summary-value text-2xl font-bold" :class="getSuccessRateClass(successRate)">{{ successRate }}%</div>
              <div class="summary-detail text-xs text-gray-500">完成的扫描任务比例</div>
            </div>
          </div>
        </div>
      </el-card>
    </div>

    <!-- 最近扫描任务 - 增强版 -->
    <el-card class="recent-scans-card card-shadow-hover border-light">
      <template #header>
        <div class="card-header flex items-center justify-between">
          <div class="header-left flex items-center">
            <el-icon class="header-icon text-primary"><el-icon-History /></el-icon>
            <span class="header-title text-lg font-semibold">最近扫描任务</span>
            <el-tag size="small" type="primary" effect="light" class="ml-2">
              共 {{ filteredScans.length }} 个任务
            </el-tag>
          </div>
          <div class="card-actions flex items-center gap-2">
            <!-- 批量操作 -->
            <el-dropdown @command="handleBatchAction" class="batch-actions" v-if="selectedTasks.length > 0">
              <el-button size="small" type="warning" plain>
                <el-icon><el-icon-Select /></el-icon>
                已选择 {{ selectedTasks.length }}
                <el-icon class="el-icon--right"><el-icon-CaretBottom /></el-icon>
              </el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item command="exportSelected" icon="el-icon-Download">导出选中</el-dropdown-item>
                  <el-dropdown-item command="deleteSelected" icon="el-icon-Delete" danger>删除选中</el-dropdown-item>
                  <el-dropdown-item command="rescanSelected" icon="el-icon-Refresh">重新扫描</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
            
            <!-- 任务筛选 -->
            <el-select v-model="scanStatusFilter" size="small" placeholder="筛选状态" class="status-filter rounded-full">
              <el-option label="全部" value=""></el-option>
              <el-option label="运行中" value="running"></el-option>
              <el-option label="已完成" value="completed"></el-option>
              <el-option label="已取消" value="cancelled"></el-option>
              <el-option label="失败" value="failed"></el-option>
            </el-select>
            
            <!-- 搜索 -->
            <el-input 
              v-model="scanSearchQuery" 
              placeholder="搜索扫描目标" 
              size="small"
              prefix-icon="el-icon-Search"
              clearable
              class="scan-search rounded-full w-48"
              @keyup.enter="updateScanList"
            />
            
            <!-- 新建任务按钮 -->
            <el-button type="primary" size="small" @click="goToScanPage" class="new-task-btn rounded-full">
              <el-icon><el-icon-Plus /></el-icon> 提交新任务
            </el-button>
          </div>
        </div>
      </template>
      
      <div class="recent-scans-content">
        <!-- 扫描任务表格 -->
        <el-table 
          v-if="filteredScans.length > 0" 
          :data="paginatedScans" 
          style="width: 100%"
          class="recent-scans-table card-shadow"
          row-class-name="scan-row hover:bg-primary/5 transition-colors"
          @selection-change="handleSelectionChange"
          v-loading="isLoadingScans"
          element-loading-text="加载扫描任务..."
          stripe
          border
        >
          <!-- 复选框 -->
          <el-table-column type="selection" width="55" />
          
          <!-- 扫描目标 -->
          <el-table-column prop="target" label="扫描目标" width="300">
            <template #default="scope">
              <div class="target-cell">
                <el-icon class="url-icon"><el-icon-Link /></el-icon>
                <div class="target-info">
                  <div class="target-url">{{ truncateText(scope.row.target, 60) }}</div>
                  <div class="target-meta">
                    <span class="target-id">ID: {{ scope.row.scan_id || 'N/A' }}</span>
                    <span class="target-type" v-if="scope.row.target_type">
                      <el-tag size="small" effect="plain">{{ scope.row.target_type }}</el-tag>
                    </span>
                  </div>
                </div>
              </div>
            </template>
          </el-table-column>
          
          <!-- 扫描深度 -->
          <el-table-column prop="scan_depth" label="扫描深度" width="100">
            <template #default="scope">
              <el-tooltip :content="getDepthDescription(scope.row.scan_depth)" placement="top">
                <span>{{ scope.row.scan_depth }}</span>
              </el-tooltip>
            </template>
          </el-table-column>
          
          <!-- 漏洞数量 -->
          <el-table-column prop="vulnerability_count" label="漏洞数量" width="140">
            <template #default="scope">
              <div class="vuln-stats" v-if="scope.row.vulnerability_details">
                <div class="vuln-badges">
                  <el-tooltip content="高危漏洞" placement="top">
                    <el-badge 
                      :value="scope.row.vulnerability_details.high || 0" 
                      type="danger" 
                      class="vuln-badge"
                    ></el-badge>
                  </el-tooltip>
                  <el-tooltip content="中危漏洞" placement="top">
                    <el-badge 
                      :value="scope.row.vulnerability_details.medium || 0" 
                      type="warning" 
                      class="vuln-badge"
                    ></el-badge>
                  </el-tooltip>
                  <el-tooltip content="低危漏洞" placement="top">
                    <el-badge 
                      :value="scope.row.vulnerability_details.low || 0" 
                      type="info" 
                      class="vuln-badge"
                    ></el-badge>
                  </el-tooltip>
                </div>
                <div class="total-vulns" :class="getVulnCountClass(scope.row.vulnerability_count || 0)">
                  总计: {{ scope.row.vulnerability_count || 0 }}
                </div>
              </div>
              <span 
                v-else 
                :class="getVulnCountClass(scope.row.vulnerability_count || 0)"
              >
                {{ scope.row.vulnerability_count || 0 }}
              </span>
            </template>
          </el-table-column>
          
          <!-- 状态 -->
          <el-table-column prop="status" label="状态" width="120">
            <template #default="scope">
              <div class="status-container">
                <el-tag 
                  :type="getStatusType(scope.row.status)"
                  effect="dark"
                  class="status-tag"
                >
                  {{ getStatusText(scope.row.status) }}
                </el-tag>
                <!-- 进度条 - 仅在运行中时显示 -->
                <el-progress 
                  v-if="scope.row.status === 'running' && scope.row.progress" 
                  :percentage="scope.row.progress" 
                  :text-inside="true"
                  :stroke-width="6"
                  :color="progressColors"
                  class="status-progress"
                ></el-progress>
                <!-- 执行时间 - 仅在已完成时显示 -->
                <div 
                  v-if="scope.row.status === 'completed' && scope.row.execution_time" 
                  class="execution-time"
                >
                  耗时: {{ formatDuration(scope.row.execution_time) }}
                </div>
              </div>
            </template>
          </el-table-column>
          
          <!-- 扫描器 -->
          <el-table-column prop="scanner_id" label="扫描器" width="100">
            <template #default="scope">
              <el-tooltip 
                :content="`扫描器 ${scope.row.scanner_id || 'N/A'}`" 
                placement="top"
              >
                <span class="scanner-id">#{{ scope.row.scanner_id || 'N/A' }}</span>
              </el-tooltip>
            </template>
          </el-table-column>
          
          <!-- 创建时间 -->
          <el-table-column prop="created_at" label="创建时间" width="180">
            <template #default="scope">
              <el-tooltip 
                :content="formatDateTime(scope.row.created_at)" 
                placement="top"
              >
                <span class="relative-time">
                  {{ formatRelativeTime(scope.row.created_at) }}
                </span>
              </el-tooltip>
            </template>
          </el-table-column>
          
          <!-- 操作 -->
          <el-table-column label="操作" width="220" fixed="right">
            <template #default="scope">
              <div class="action-buttons flex gap-1">
                <!-- 查看结果按钮 -->
                <el-button 
                  type="primary" 
                  size="small" 
                  @click="viewScanResult(scope.row.scan_id)"
                  :disabled="scope.row.status !== 'completed'"
                  class="action-btn rounded-full"
                  title="查看扫描结果"
                >
                  <el-icon><el-icon-Document /></el-icon> 结果
                </el-button>
                
                <!-- 取消按钮 - 仅在运行中时显示 -->
                <el-button 
                  type="danger" 
                  size="small" 
                  @click="confirmCancelScan(scope.row.scan_id, scope.row.target)"
                  v-if="scope.row.status === 'running'"
                  class="action-btn rounded-full"
                  title="取消扫描"
                >
                  <el-icon><el-icon-Cancel /></el-icon> 取消
                </el-button>
                
                <!-- 重新扫描按钮 - 仅在非运行中时显示 -->
                <el-button 
                  type="default" 
                  size="small" 
                  @click="rescanTarget(scope.row.target)"
                  v-else
                  class="action-btn rounded-full"
                  title="重新扫描"
                >
                  <el-icon><el-icon-Refresh /></el-icon> 重扫
                </el-button>
                
                <!-- 详情按钮 - 所有状态都显示 -->
                <el-button 
                  type="info" 
                  size="small" 
                  plain
                  @click="viewScanDetails(scope.row.scan_id)"
                  class="action-btn rounded-full"
                  title="查看详情"
                >
                  <el-icon><el-icon-View /></el-icon>
                </el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
        
        <!-- 空状态 -->
        <div v-else class="empty-scans">
          <el-empty 
            description="暂无扫描任务记录" 
            image-size="120" 
            class="empty-state"
          >
            <el-button type="primary" @click="goToScanPage">开始新扫描</el-button>
          </el-empty>
        </div>
        
        <!-- 分页 -->
        <div class="pagination-container" v-if="filteredScans.length > 0">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next, jumper"
            :total="filteredScans.length"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            class="scan-pagination"
          />
        </div>
      </div>
    </el-card>

    <!-- 系统服务状态 -->
    <el-card class="system-status-card card-shadow-hover border-light">
      <template #header>
        <div class="card-header flex items-center justify-between">
          <div class="header-left flex items-center">
            <el-icon class="header-icon text-primary"><More /></el-icon>
            <span class="header-title text-lg font-semibold">服务状态监控</span>
            <el-tag 
              :type="getSystemHealthType" 
              size="small" 
              effect="light" 
              class="ml-2"
            >
              {{ getSystemHealthStatus }}
            </el-tag>
          </div>
          <el-button 
            type="info" 
            size="small" 
            plain 
            class="rounded-full"
            @click="refreshServiceStatus"
          >
            <el-icon><Refresh /></el-icon> 刷新状态
          </el-button>
        </div>
      </template>
      
      <div class="service-status-grid grid grid-cols-1 md:grid-cols-2 gap-4 mt-2">
        <div class="service-item p-4 rounded-xl transition-all duration-300 hover:scale-[1.02]" :class="getServiceStatusClass(apiServiceStatus)">
          <div class="service-icon-container">
            <el-icon class="service-icon text-2xl"><Link /></el-icon>
            <div class="status-indicator" :class="apiServiceStatus"></div>
          </div>
          <div class="service-info">
            <div class="service-header">
              <h4 class="service-name font-medium">Flask API</h4>
              <el-tag 
                :type="apiServiceStatus === 'running' ? 'success' : 'danger'" 
                size="small" 
                class="status-tag"
              >
                {{ apiServiceStatus === 'running' ? '运行中' : '已停止' }}
              </el-tag>
            </div>
            <p class="service-url text-sm text-gray-600">
              <el-icon class="mr-1"><Link /></el-icon>
              <a href="http://localhost:5000" target="_blank" class="hover:text-primary">http://localhost:5000</a>
            </p>
            <div class="service-metrics flex items-center mt-1">
              <div class="metric-item">
                <span class="metric-label">响应时间:</span>
                <span class="metric-value" :class="getResponseTimeClass(apiResponseTime)">{{ apiResponseTime }}ms</span>
              </div>
            </div>
          </div>
        </div>

        <div class="service-item p-4 rounded-xl transition-all duration-300 hover:scale-[1.02]" :class="getServiceStatusClass(celeryServiceStatus)">
          <div class="service-icon-container">
            <el-icon class="service-icon text-2xl"><Operation /></el-icon>
            <div class="status-indicator" :class="celeryServiceStatus"></div>
          </div>
          <div class="service-info">
            <div class="service-header">
              <h4 class="service-name font-medium">Celery Worker</h4>
              <el-tag 
                :type="celeryServiceStatus === 'running' ? 'success' : 'danger'" 
                size="small" 
                class="status-tag"
              >
                {{ celeryServiceStatus === 'running' ? '运行中' : '已停止' }}
              </el-tag>
            </div>
            <p class="service-details text-sm text-gray-600">任务队列状态</p>
            <div class="service-metrics flex items-center gap-3 mt-1">
              <div class="metric-item">
                <span class="metric-label">活跃任务:</span>
                <span class="metric-value">{{ celeryTasks.active }}</span>
              </div>
              <div class="metric-item">
                <span class="metric-label">总计任务:</span>
                <span class="metric-value">{{ celeryTasks.total }}</span>
              </div>
              <div class="metric-item">
                <span class="metric-label">成功率:</span>
                <span class="metric-value" :class="getSuccessRateClass(celeryTaskSuccessRate)">{{ celeryTaskSuccessRate }}%</span>
              </div>
            </div>
          </div>
        </div>

        <div class="service-item p-4 rounded-xl transition-all duration-300 hover:scale-[1.02]" :class="getServiceStatusClass(redisServiceStatus)">
          <div class="service-icon-container">
            <el-icon class="service-icon text-2xl"><Link /></el-icon>
            <div class="status-indicator" :class="redisServiceStatus"></div>
          </div>
          <div class="service-info">
            <div class="service-header">
              <h4 class="service-name font-medium">Redis</h4>
              <el-tag 
                :type="redisServiceStatus === 'running' ? 'success' : 'danger'" 
                size="small" 
                class="status-tag"
              >
                {{ redisServiceStatus === 'running' ? '运行中' : '已停止' }}
              </el-tag>
            </div>
            <p class="service-details text-sm text-gray-600">内存使用情况</p>
            <div class="service-metrics mt-1">
              <el-progress 
                :percentage="getRedisMemoryUsage()" 
                :status="getRedisMemoryStatus()"
                class="memory-progress"
                show-text
              ></el-progress>
              <div class="memory-details text-xs text-gray-500 mt-1">
                {{ redisInfo.used_memory }} / {{ redisInfo.max_memory }} MB
              </div>
              <div class="metric-item mt-1">
                <span class="metric-label">连接数:</span>
                <span class="metric-value">{{ redisConnections }}</span>
              </div>
            </div>
          </div>
        </div>

        <div class="service-item p-4 rounded-xl transition-all duration-300 hover:scale-[1.02]" :class="getServiceStatusClass(streamlitServiceStatus)">
          <div class="service-icon-container">
            <el-icon class="service-icon text-2xl"><Link /></el-icon>
            <div class="status-indicator" :class="streamlitServiceStatus"></div>
          </div>
          <div class="service-info">
            <div class="service-header">
              <h4 class="service-name font-medium">Streamlit</h4>
              <el-tag 
                :type="streamlitServiceStatus === 'running' ? 'success' : 'danger'" 
                size="small" 
                class="status-tag"
              >
                {{ streamlitServiceStatus === 'running' ? '运行中' : '已停止' }}
              </el-tag>
            </div>
            <p class="service-url text-sm text-gray-600">
              <el-icon class="mr-1"><Link /></el-icon>
              <a href="http://localhost:8501" target="_blank" class="hover:text-primary">http://localhost:8501</a>
            </p>
            <div class="service-metrics flex items-center mt-1">
              <div class="metric-item">
                <span class="metric-label">用途:</span>
                <span class="metric-value">数据可视化</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <div class="service-summary mt-4 p-3 bg-gray-50 rounded-lg">
        <div class="summary-row flex justify-between items-center">
          <div class="summary-label">系统状态更新时间:</div>
          <div class="summary-value text-sm text-gray-600">
            {{ formatDateTime(lastUpdated) }}
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup>
  import { ref, computed, onMounted, nextTick, onUnmounted, watch } from 'vue'
  import { ElMessage, ElMessageBox } from 'element-plus'
  import { useRouter } from 'vue-router'
  import * as echarts from 'echarts'
  import apiService from '../services/apiService.js'
  import exportService from '../services/exportService.js'
  import AdvancedStats from '../components/AdvancedStats.vue'
  import NotificationCenter from '../components/NotificationCenter.vue'
  import { Refresh, Link, Operation, SuccessFilled, WarningFilled, Clock, CircleCheck, Search, More, CaretTop, CaretBottom } from '@element-plus/icons-vue'
  
  // 保存window错误处理函数引用，用于组件卸载时移除
  let windowErrorHandler = null
  
  // 设置组件级错误处理，防止'Cannot read properties of null/undefined'错误
  const setupErrorHandling = () => {
    // 添加Vue组件级错误处理
    const originalErrorHandler = console.error
    console.error = (...args) => {
      if (args[0] && typeof args[0] === 'string' && 
          (args[0].includes('Cannot read properties of') || args[0].includes('Cannot read property'))) {
        // 捕获并记录属性访问错误，但不传播到控制台以避免用户看到错误
        console.warn('安全捕获到属性访问错误:', args[0])
        return
      }
      originalErrorHandler.apply(console, args)
    }
    
    // 添加全局window错误处理作为后备
    windowErrorHandler = (event) => {
      if (event.error && event.error.message && 
          (event.error.message.includes('Cannot read properties of') || 
           event.error.message.includes('Cannot read property'))) {
        console.warn('全局捕获到属性访问错误:', event.error.message)
        event.preventDefault() // 阻止错误传播
        return true
      }
      return false
    }
    
    window.addEventListener('error', windowErrorHandler)
    
    // 在组件卸载时清理
    onUnmounted(() => {
      console.error = originalErrorHandler
      if (windowErrorHandler) {
        window.removeEventListener('error', windowErrorHandler)
        windowErrorHandler = null
      }
    })
  }
  
  // 立即调用错误处理设置
  setupErrorHandling()

// 文本截断函数 - 提前定义供表格使用
const truncateText = (text, maxLength = 30) => {
  if (!text || typeof text !== 'string') return ''
  if (text.length <= maxLength) return text
  return text.substring(0, maxLength) + '...'
}

// 路由实例
const router = useRouter()

// 系统指标
const totalScans = ref(42)
const totalVulnerabilities = ref(156)
const highRiskVulnerabilities = ref(38)
const mediumRiskVulnerabilities = ref(65)
const lowRiskVulnerabilities = ref(53)
const scansChange = ref(5)
const highRiskChange = ref(2)
const vulnsChange = ref(-8)
  
  // 安全态势概览指标 - 解决NaN显示问题
  const todayScans = ref(12)
  const todayScansChange = ref(8)
  const todayVulnerabilities = ref(24)
  const todayVulnerabilitiesChange = ref(-5)
  const criticalVulnerabilities = ref(15)
  const criticalVulnerabilitiesChange = ref(3)
  const avgRemediationTime = ref(48)
  const avgRemediationTimeChange = ref(-12)
  const overviewTimeRange = ref('today')
  
  // 新增：扫描任务筛选和分页
const scanTasks = ref([])
const selectedTasks = ref([])
const currentPage = ref(1)
const pageSize = ref(10)
const totalTasks = ref(0)
const taskFilter = ref('all')
const searchQuery = ref('')
// 扫描任务筛选相关变量
const scanStatusFilter = ref('')
const scanSearchQuery = ref('')
// 移除重复的selectedScans变量，统一使用selectedTasks
const dateRange = ref([])
const dateRangeShortcuts = [
  { text: '今天', value: () => [new Date(), new Date()] },
  { text: '昨天', value: () => {
    const yesterday = new Date()
    yesterday.setDate(yesterday.getDate() - 1)
    return [yesterday, yesterday]
  }},
  { text: '最近7天', value: () => {
    const today = new Date()
    const sevenDaysAgo = new Date()
    sevenDaysAgo.setDate(today.getDate() - 7)
    return [sevenDaysAgo, today]
  }},
  { text: '最近30天', value: () => {
    const today = new Date()
    const thirtyDaysAgo = new Date()
    thirtyDaysAgo.setDate(today.getDate() - 30)
    return [thirtyDaysAgo, today]
  }}
]

// 新增：数据过滤
const dataFilter = ref('all') // 'all', 'high-risk', 'last-30-days', 'custom'
const viewMode = ref('card') // 'card', 'list', 'compact'
const autoRefreshEnabled = ref(false)
const autoRefreshInterval = ref(30) // 秒
let refreshTimer = null

// 新增：进度条颜色配置
const getProgressColor = (percentage) => {
  if (percentage < 30) return '#10b981'
  if (percentage < 70) return '#f59e0b'
  return '#ef4444'
}

// 新增：格式化时间函数
const formatDateTime = (date) => {
  if (!date) return ''
  const d = new Date(date)
  return d.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

// 新增：获取相对时间
const getRelativeTime = (date) => {
  if (!date) return ''
  const now = new Date()
  const diffMs = now - new Date(date)
  const diffSecs = Math.floor(diffMs / 1000)
  const diffMins = Math.floor(diffSecs / 60)
  const diffHours = Math.floor(diffMins / 60)
  const diffDays = Math.floor(diffHours / 24)
  
  if (diffSecs < 60) return `${diffSecs}秒前`
  if (diffMins < 60) return `${diffMins}分钟前`
  if (diffHours < 24) return `${diffHours}小时前`
  return `${diffDays}天前`
}

// 新增：批量操作函数 - 优化版
const handleBatchDelete = () => {
  if (selectedTasks.value.length === 0) {
    ElMessage.warning('请先选择要删除的任务')
    return
  }
  
  ElMessageBox.confirm(
    `确定要删除选中的 ${selectedTasks.value.length} 个扫描任务吗？此操作不可恢复。`,
    '确认删除',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
      center: true
    }
  ).then(async () => {
    try {
      // 模拟API调用
      await new Promise(resolve => setTimeout(resolve, 500))
      ElMessage.success('删除成功')
      selectedTasks.value = []
      loadScanTasks()
      
      // 添加操作成功通知
      if (notificationCenterRef.value) {
        notificationCenterRef.value.addNotification({
          type: 'success',
          title: '批量删除成功',
          message: '已成功删除选中的扫描任务'
        })
      }
    } catch (error) {
      ElMessage.error('删除失败，请重试')
    }
  }).catch(() => {})
}

const handleBatchCancel = () => {
  if (selectedTasks.value.length === 0) {
    ElMessage.warning('请先选择要取消的任务')
    return
  }
  
  // 这里调用API取消任务
  ElMessage.success('已取消选中任务')
  selectedTasks.value = []
  loadScanTasks()
}

// 新增：加载扫描任务
const loadScanTasks = async () => {
  try {
    // 使用apiService.getScans获取扫描任务列表
    const response = await apiService.getScans();
    
    // 处理响应数据
    if (response && response.success && response.data) {
      // 转换数据格式以匹配组件需求
      scanTasks.value = response.data.map(scan => ({
        id: scan.id || scan.task_id,
        target: scan.target,
        depth: scan.scanDepth || scan.type || 'standard',
        vulnerabilities: scan.vulnerabilities?.total || scan.vulnerability_count || 0,
        status: scan.status,
        scanner: 'Scanner-1', // 默认值，实际项目中可能从API获取
        createdAt: new Date(scan.createdAt || scan.startTime || Date.now())
      }));
      totalTasks.value = response.total || scanTasks.value.length;
    } else {
      // 如果响应格式不正确，使用示例数据作为后备
      scanTasks.value = [
        { id: 1, target: 'https://example.com', depth: 'deep', vulnerabilities: 12, status: 'completed', scanner: 'Scanner-1', createdAt: new Date() },
        { id: 2, target: 'https://test.org', depth: 'standard', vulnerabilities: 5, status: 'running', scanner: 'Scanner-2', createdAt: new Date() },
        { id: 3, target: 'https://sample.net', depth: 'quick', vulnerabilities: 0, status: 'pending', scanner: 'Scanner-3', createdAt: new Date() },
      ]
      totalTasks.value = scanTasks.value.length
    }
  } catch (error) {
    console.error('加载扫描任务失败:', error);
    ElMessage.error('加载扫描任务失败');
    
    // 错误时使用示例数据作为后备
    scanTasks.value = [
      { id: 1, target: 'https://example.com', depth: 'deep', vulnerabilities: 12, status: 'completed', scanner: 'Scanner-1', createdAt: new Date() },
      { id: 2, target: 'https://test.org', depth: 'standard', vulnerabilities: 5, status: 'running', scanner: 'Scanner-2', createdAt: new Date() },
      { id: 3, target: 'https://sample.net', depth: 'quick', vulnerabilities: 0, status: 'pending', scanner: 'Scanner-3', createdAt: new Date() },
    ]
    totalTasks.value = scanTasks.value.length
  }
}

// 新增：初始化概览趋势图表
const initOverviewTrendChart = () => {
  // 增强健壮性，添加多重检查 - 修复路由切换时的引用错误
  if (!overviewTrendChartRef || !overviewTrendChartRef.value || !overviewTrendChartRef.value.parentNode) {
    console.warn('概览趋势图表引用未定义或DOM结构不完整')
    return
  }
  
  // 安全销毁现有图表
  if (overviewTrendChartInstance && overviewTrendChartInstance.value && typeof overviewTrendChartInstance.value.dispose === 'function') {
    try {
      overviewTrendChartInstance.value.dispose()
      overviewTrendChartInstance.value = null
    } catch (error) {
      console.warn('销毁现有概览趋势图表时出错:', error)
      overviewTrendChartInstance.value = null
    }
  }
  
  try {
    // 创建新图表
    overviewTrendChartInstance.value = echarts.init(overviewTrendChartRef.value)
    
    // 添加自动销毁保护
    overviewTrendChartInstance.value._dom._chart_ = overviewTrendChartInstance
    
    // 基础图表配置 - 可以根据实际需求调整
    const option = {
      tooltip: {
        trigger: 'axis',
        backgroundColor: 'rgba(255, 255, 255, 0.95)',
        borderColor: '#d9d9d9',
        borderRadius: 8,
        textStyle: {
          color: '#333'
        }
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: [],
        axisLabel: {
          color: '#666'
        }
      },
      yAxis: {
        type: 'value',
        axisLabel: {
          color: '#666'
        }
      },
      series: []
    }
    
    // 设置图表配置
    if (overviewTrendChartInstance.value) {
      overviewTrendChartInstance.value.setOption(option)
    }
  } catch (error) {
    console.warn('初始化概览趋势图表时出错:', error)
    overviewTrendChartInstance.value = null
    return
  }
}

// 新增：刷新图表
const refreshCharts = () => {
  // 重新初始化图表
  initVulnerabilityChart()
  initScanTrendChart()
  initRiskTrendChart()
  initOverviewTrendChart()
}

// 数据导出函数 - 增强版
const exportData = async (format) => {
  try {
    // 准备导出数据
    const exportData = {
      title: '漏洞扫描系统仪表盘报告',
      dateRange: dateRange.value ? `${dateRange.value[0].toLocaleDateString()} 至 ${dateRange.value[1].toLocaleDateString()}` : '全部时间',
      summary: {
        totalScans: totalScans.value,
        totalVulnerabilities: totalVulnerabilities.value,
        highRiskVulnerabilities: highRiskVulnerabilities.value,
        mediumRiskVulnerabilities: mediumRiskVulnerabilities.value,
        lowRiskVulnerabilities: lowRiskVulnerabilities.value,
        scansChange: scansChange.value,
        vulnsChange: vulnsChange.value,
        highRiskChange: highRiskChange.value,
        securityScore: securityScore.value,
        securityScoreChange: securityScoreChange.value
      },
      generatedAt: new Date().toISOString(),
      scanTasks: scanTasks.value
    }
    
    // 根据格式导出数据
    switch (format) {
      case 'pdf':
        exportService.exportDashboard(exportData, 'pdf', 'vulnerability_dashboard_report')
        break
      case 'excel':
        exportService.exportDashboard(exportData, 'excel', 'vulnerability_dashboard_report')
        break
      case 'json':
        exportService.exportDashboard(exportData, 'json', 'vulnerability_dashboard_data')
        break
      case 'charts':
        // 导出图表
        if (vulnerabilityChartInstance.value) {
          exportService.exportChartAsImage(vulnerabilityChartRef.value, 'vulnerability_distribution.png')
        }
        break
      default:
        throw new Error('不支持的导出格式')
    }
    
    ElMessage.success(`数据已成功导出为 ${format.toUpperCase()} 格式`)
    
    // 添加导出成功通知
    if (notificationCenterRef.value) {
      notificationCenterRef.value.addNotification({
        type: 'success',
        title: '数据导出成功',
        message: `仪表盘数据已导出为 ${format.toUpperCase()} 格式`
      })
    }
  } catch (error) {
    console.error('导出数据失败:', error)
    ElMessage.error(`导出失败: ${error.message}`)
  }
}

// 新增：设置自动刷新
const setupAutoRefresh = () => {
  if (autoRefreshEnabled.value) {
    // 安全清除现有定时器
    if (refreshTimer) {
      clearInterval(refreshTimer)
      refreshTimer = null
    }
    // 创建新的定时器
    refreshTimer = setInterval(() => {
      try {
        loadScanTasks()
        refreshCharts()
      } catch (error) {
        console.warn('自动刷新任务执行出错:', error)
      }
    }, autoRefreshInterval.value * 1000)
  } else if (refreshTimer) {
    clearInterval(refreshTimer)
    refreshTimer = null
  }
}

// 新增：资源使用状态类名
const getResourceClass = (usage) => {
  if (usage < 50) return 'healthy'
  if (usage < 80) return 'warning'
  return 'critical'
}

// 新增：获取成功率样式类
const getSuccessRateClass = (rate) => {
  if (rate >= 95) return 'high-success'
  if (rate >= 80) return 'medium-success'
  return 'low-success'
}

// 新增：系统负载颜色
const getLoadColor = (load) => {
  if (load < 30) return '#10b981'
  if (load < 70) return '#f59e0b'
  return '#ef4444'
}

// 新增：获取系统负载样式类名
const getLoadTextClass = (load) => {
  if (load < 30) return 'load-healthy'
  if (load < 70) return 'load-warning'
  return 'load-critical'
}

// truncateText函数已移至顶部定义

// 新增：获取评分颜色
const getScoreColor = (score) => {
  if (score >= 90) return '#67c23a' // 优秀 - 绿色
  if (score >= 80) return '#909399' // 良好 - 灰色
  if (score >= 70) return '#e6a23c' // 一般 - 橙色
  if (score >= 60) return '#f56c6c' // 较差 - 红色
  return '#ff4d4f' // 危险 - 深红色
}

// 新增：获取等级样式类名
const getGradeClass = (grade) => {
  const gradeMap = {
    '优秀': 'grade-excellent',
    '良好': 'grade-good',
    '一般': 'grade-fair',
    '较差': 'grade-poor',
    '危险': 'grade-critical'
  }
  return gradeMap[grade] || ''
}

// 监听自动刷新设置变化
watch(autoRefreshEnabled, setupAutoRefresh)
watch(autoRefreshInterval, setupAutoRefresh)

// 组件卸载时清理定时器
onUnmounted(() => {
  if (refreshTimer) {
    clearInterval(refreshTimer)
  }
})
// 移除重复的vulnsChange变量声明，已在系统指标部分声明
const isRefreshing = ref(false)
const securityScore = ref(75)
const apiResponseTime = ref(45)
// 复用前面已定义的autoRefreshEnabled和autoRefreshInterval变量
const timeUntilRefresh = ref(30000)
const autoRefreshTimer = ref(null)
const refreshIntervalTimer = ref(null)
const isCheckingServices = ref(false)
// 复用前面已定义的dateRange变量
const redisConnections = ref(10)
const celeryTaskSuccessRate = ref(95)
const lastUpdated = ref(new Date())

// 图表引用定义
const vulnerabilityChartRef = ref(null)
const scanTrendChartRef = ref(null)
const riskTrendChartRef = ref(null)
const overviewTrendChartRef = ref(null)

// 定时器引用
const chartInitTimerRef = ref(null)

// 通知中心引用
const notificationCenterRef = ref(null)

// 高级统计数据
const advancedStatsData = ref([
  {
    value: '92%',
    label: '漏洞修复率',
    change: 6,
    changeType: 'positive',
    changePeriod: '较上月',
    icon: SuccessFilled,
    iconClass: 'success',
    highlight: true
  },
  {
    value: '8',
    label: '未修复高危漏洞',
    change: -2,
    changeType: 'negative',
    changePeriod: '较上周',
    icon: WarningFilled,
    iconClass: 'warning'
  },
  {
    value: '36h',
    label: '平均响应时间',
    change: -15,
    changeType: 'negative',
    changePeriod: '较上月',
    icon: Clock,
    iconClass: 'info'
  },
  {
    value: '98%',
    label: '资产覆盖率',
    change: 3,
    changeType: 'positive',
    changePeriod: '较上周',
    icon: CircleCheck,
    iconClass: 'success'
  }
])

// 处理通知点击
const handleNotificationClick = (notification) => {
  console.log('Notification clicked:', notification)
  // 根据通知类型进行相应处理
  if (notification.type === 'vulnerability') {
    router.push('/results')
  } else if (notification.type === 'system' && notification.title.includes('扫描任务')) {
    router.push('/scan')
  }
}

// 处理通知操作按钮点击
const handleNotificationAction = (notification) => {
  console.log('Notification action clicked:', notification)
  // 根据通知类型执行不同操作
  if (notification.type === 'vulnerability') {
    ElMessage.info('正在跳转到漏洞详情页面...')
    router.push('/results')
  }
}

// 获取服务状态样式类
const getServiceStatusClass = (status) => {
  return status === 'running' ? 'bg-success/5 border border-success/20' : 'bg-danger/5 border border-danger/20'
}

// 获取系统健康类型
const getSystemHealthType = computed(() => {
  const services = [apiServiceStatus.value, celeryServiceStatus.value, redisServiceStatus.value, streamlitServiceStatus.value]
  const runningCount = services.filter(s => s === 'running').length
  
  if (runningCount === services.length) return 'success'
  if (runningCount > 0) return 'warning'
  return 'danger'
})

// 获取系统健康状态
const getSystemHealthStatus = computed(() => {
  const services = [apiServiceStatus.value, celeryServiceStatus.value, redisServiceStatus.value, streamlitServiceStatus.value]
  const runningCount = services.filter(s => s === 'running').length
  
  if (runningCount === services.length) return '全部正常'
  if (runningCount > 0) return '部分异常'
  return '全部异常'
})

// 刷新服务状态
const refreshServiceStatus = async () => {
  isCheckingServices.value = true
  try {
    // 模拟API调用
    await new Promise(resolve => setTimeout(resolve, 1000))
    // 更新最后更新时间
    lastUpdated.value = new Date()
    ElMessage.success('服务状态已刷新')
  } catch (error) {
    ElMessage.error('刷新服务状态失败')
  } finally {
    isCheckingServices.value = false
  }
}

// 获取Redis内存使用率 - 修复响应式数据访问
const getRedisMemoryUsage = () => {
  try {
    const used = parseFloat(redisInfo.value.used_memory)
    const max = parseFloat(redisInfo.value.max_memory)
    return max > 0 ? Math.round((used / max) * 100) : 0
  } catch {
    return 0
  }
}

// 获取Redis内存状态
const getRedisMemoryStatus = () => {
  const usage = getRedisMemoryUsage()
  if (usage > 80) return 'exception'
  if (usage > 70) return 'warning'
  return 'success'
}

// 获取响应时间样式类
const getResponseTimeClass = (time) => {
  if (time < 100) return 'text-success'
  if (time < 500) return 'text-warning'
  return 'text-danger'
}

// 查看扫描详情
const viewScanDetails = (scanId) => {
  router.push({ path: '/scan-details', query: { id: scanId } })
}

// 获取趋势样式类
const getTrendClass = (change) => {
  if (change > 0) return 'trend-positive'
  if (change < 0) return 'trend-negative'
  return 'trend-neutral'
}

// 获取最高扫描次数
const getHighestScanCount = () => {
  if (!scanTrendData.value.scans || scanTrendData.value.scans.length === 0) return 0
  return Math.max(...scanTrendData.value.scans)
}

// 重置图表2筛选器
const resetChart2Filter = () => {
  showScanCount.value = true
  showVulnerabilityCount.value = true
  showSuccessRate.value = true
}

// 图表2可见系列
const chart2VisibleSeries = ref(['scanCount', 'vulnerabilityCount', 'successRate'])
const vulnerabilityChartInstance = ref(null)
const scanTrendChartInstance = ref(null)
const riskTrendChartInstance = ref(null)
const overviewTrendChartInstance = ref(null)

// 图表类型选择
const chartType1 = ref('pie') // pie, bar
const chartType2 = ref('line') // line, area

// 系统状态
const systemStatus = ref('healthy') // healthy, warning, critical
const systemStatusText = computed(() => {
  switch(systemStatus.value) {
    case 'healthy': return '运行正常'
    case 'warning': return '需要注意'
    case 'critical': return '存在严重问题'
    default: return '未知状态'
  }
})

// 安全评分等级计算
const securityGrade = computed(() => {
  if (securityScore.value >= 90) return '优秀'
  if (securityScore.value >= 75) return '良好'
  if (securityScore.value >= 60) return '一般'
  if (securityScore.value >= 40) return '较差'
  return '危险'
})

// 安全评分变化计算
const securityScoreChange = computed(() => {
  // 模拟计算，实际应该从API获取
  return Math.floor(Math.random() * 5) - 2
})

// 计算扫描效率指标
const vulnsPerScan = computed(() => {
  return totalScans.value > 0 ? (totalVulnerabilities.value / totalScans.value).toFixed(1) : '0.0'
})

// 计算高风险漏洞占比
const highRiskPercentage = computed(() => {
  return totalVulnerabilities.value > 0 
    ? ((highRiskVulnerabilities.value / totalVulnerabilities.value) * 100).toFixed(1)
    : '0.0'
})

// 过滤扫描任务 - 修复"Cannot read properties of null (reading 'value')"错误
const filteredScans = computed(() => {
  // 确保recentScans是数组
  const scans = Array.isArray(recentScans.value) ? recentScans.value : []
  
  // 根据状态筛选
  let filtered = scans
  if (scanStatusFilter && scanStatusFilter.value) {
    filtered = filtered.filter(scan => scan && scan.status === scanStatusFilter.value)
  }
  
  // 根据搜索关键词筛选
  if (scanSearchQuery && scanSearchQuery.value) {
    const query = scanSearchQuery.value.toLowerCase()
    filtered = filtered.filter(scan => 
      scan && scan.target && typeof scan.target === 'string' && scan.target.toLowerCase().includes(query)
    )
  }
  
  return filtered
})

// 分页扫描任务
const paginatedScans = computed(() => {
  const startIndex = (currentPage.value - 1) * pageSize.value
  const endIndex = startIndex + pageSize.value
  return filteredScans.value.slice(startIndex, endIndex)
})

// 处理分页大小变化
const handleSizeChange = (size) => {
  pageSize.value = size
  currentPage.value = 1
}

// 处理当前页码变化
const handleCurrentChange = (current) => {
  currentPage.value = current
}

// 处理扫描列表更新
const updateScanList = () => {
  currentPage.value = 1
}

// 处理选择变化
const handleSelectionChange = (selection) => {
  selectedScans.value = selection
}

// 处理批量操作
const handleBatchAction = (command) => {
  switch (command) {
    case 'exportSelected':
      ElMessage.info('导出选中的扫描任务功能待实现')
      break
    case 'deleteSelected':
      confirmDeleteSelectedScans()
      break
    case 'rescanSelected':
      rescanSelectedTargets()
      break
    default:
      break
  }
}

// 确认删除选中的扫描任务
const confirmDeleteSelectedScans = () => {
  ElMessageBox.confirm(
    `确定要删除选中的 ${selectedScans.value.length} 个扫描任务吗？`,
    '确认删除',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(() => {
    // 这里应该调用API删除选中的任务
    ElMessage.success('删除成功')
    selectedScans.value = []
  }).catch(() => {})
}

// 重新扫描选中的目标
const rescanSelectedTargets = () => {
  ElMessage.info('重新扫描功能待实现')
}

// 确认取消扫描
const confirmCancelScan = (scanId, target) => {
  ElMessageBox.confirm(
    `确定要取消对 ${target} 的扫描吗？`,
    '确认取消',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(() => {
    // 这里应该调用API取消扫描
    ElMessage.success('扫描已取消')
  }).catch(() => {})
}

// 重新扫描目标
const rescanTarget = (target) => {
  router.push({ path: '/scan', query: { target } })
}

// 漏洞分布数据
const vulnerabilityDistribution = ref([
  { name: 'SQL注入', value: 42, color: '#ff6b6b' },
  { name: 'XSS', value: 38, color: '#4ecdc4' },
  { name: '信息泄露', value: 29, color: '#45b7d1' },
  { name: '命令注入', value: 25, color: '#f9c74f' },
  { name: 'CSRF', value: 22, color: '#90be6d' },
  { name: '未授权访问', value: 18, color: '#ff9f43' },
  { name: '配置错误', value: 15, color: '#54a0ff' }
])

// 扫描趋势数据
const scanTrendData = ref({
  dates: ['10/20', '10/21', '10/22', '10/23', '10/24', '10/25', '10/26'],
  scans: [5, 8, 3, 6, 7, 4, 9],
  vulnerabilities: [12, 18, 5, 15, 22, 10, 17],
  highRisk: [3, 5, 1, 4, 7, 2, 6]
})

// 风险趋势数据
const riskTrendData = ref({
  dates: ['10/20', '10/21', '10/22', '10/23', '10/24', '10/25', '10/26'],
  scores: [72, 70, 73, 71, 69, 74, 75],
  highRisk: [3, 5, 1, 4, 7, 2, 6],
  mediumRisk: [5, 8, 3, 6, 9, 4, 7],
  lowRisk: [4, 5, 1, 3, 6, 3, 4]
})

// 移除重复的setupErrorHandling函数定义
// 此函数已在文件前面定义，避免变量重复声明错误

// 安全建议
const securityTips = ref([
  {
    id: 'tip-001',
    title: '高风险漏洞过多',
    description: '检测到多个SQL注入漏洞，建议优先修复',
    severity: 'high',
    action: '立即修复'
  },
  {
    id: 'tip-002',
    title: '扫描频率偏低',
    description: '建议增加关键系统的扫描频率',
    severity: 'medium',
    action: '调整设置'
  },
  {
    id: 'tip-003',
    title: '系统安全评分提升',
    description: '相比上周，系统安全评分提升了5分',
    severity: 'low',
    action: '查看详情'
  }
])

// 最近扫描任务
const recentScans = ref([
  {
    scan_id: 'scan-001',
    target: 'https://example.com',
    scan_depth: 3,
    vulnerability_count: 8,
    high_risk_count: 3,
    medium_risk_count: 4,
    low_risk_count: 1,
    status: 'completed',
    created_at: '2023-10-26 14:30:00',
    completed_at: '2023-10-26 14:45:30',
    duration: '15分30秒'
  },
  {
    scan_id: 'scan-002',
    target: 'https://test-app.org',
    scan_depth: 2,
    vulnerability_count: 3,
    high_risk_count: 0,
    medium_risk_count: 2,
    low_risk_count: 1,
    status: 'completed',
    created_at: '2023-10-26 10:15:00',
    completed_at: '2023-10-26 10:22:15',
    duration: '7分15秒'
  },
  {
    scan_id: 'scan-003',
    target: 'https://dev-server.local',
    scan_depth: 4,
    vulnerability_count: 12,
    high_risk_count: 5,
    medium_risk_count: 4,
    low_risk_count: 3,
    status: 'completed',
    created_at: '2023-10-25 16:45:00',
    completed_at: '2023-10-25 17:10:45',
    duration: '25分45秒'
  },
  {
    scan_id: 'scan-004',
    target: 'https://production-site.com',
    scan_depth: 2,
    vulnerability_count: 0,
    high_risk_count: 0,
    medium_risk_count: 0,
    low_risk_count: 0,
    status: 'completed',
    created_at: '2023-10-25 09:20:00',
    completed_at: '2023-10-25 09:28:30',
    duration: '8分30秒'
  },
  {
    scan_id: 'scan-005',
    target: 'https://internal-api.com',
    scan_depth: 5,
    vulnerability_count: 0,
    high_risk_count: 0,
    medium_risk_count: 0,
    low_risk_count: 0,
    status: 'running',
    progress: 65,
    created_at: '2023-10-26 15:00:00'
  }
])

// 服务状态
const apiServiceStatus = ref('running')
const celeryServiceStatus = ref('running')
const redisServiceStatus = ref('running')
const streamlitServiceStatus = ref('running')

// Celery任务状态
const celeryTasks = ref({
  active: 2,
  total: 15,
  completed: 12,
  failed: 1
})

// Redis信息
const redisInfo = ref({
  used_memory: '42.5',
  max_memory: '1024',
  hit_rate: '98.5%'
})

// 性能指标
const performanceMetrics = ref({
  average_scan_time: '15.6秒',
  scan_success_rate: '97.8%',
  detection_accuracy: '92.5%'
})

// 获取状态标签类型
const getStatusType = (status) => {
  const statusMap = {
    'completed': 'success',
    'running': 'primary',
    'pending': 'warning',
    'failed': 'danger',
    'cancelled': 'info'
  }
  return statusMap[status] || 'default'
}

// 获取状态文本

// 格式化相对时间
const formatRelativeTime = (datetimeStr) => {
  if (!datetimeStr) return '';
  
  const now = new Date();
  const date = new Date(datetimeStr);
  const diffMs = now - date;
  const diffSecs = Math.floor(diffMs / 1000);
  const diffMins = Math.floor(diffSecs / 60);
  const diffHours = Math.floor(diffMins / 60);
  const diffDays = Math.floor(diffHours / 24);
  
  if (diffDays > 0) {
    return `${diffDays}天前`;
  } else if (diffHours > 0) {
    return `${diffHours}小时前`;
  } else if (diffMins > 0) {
    return `${diffMins}分钟前`;
  } else {
    return '刚刚';
  }
};

// 格式化日期时间函数已在文件其他位置定义
const getStatusText = (status) => {
  const statusMap = {
    'pending': '等待中',
    'running': '运行中',
    'completed': '已完成',
    'failed': '失败',
    'cancelled': '已取消'
  }
  return statusMap[status] || '未知'
}

// 获取扫描深度描述
const getDepthDescription = (depth) => {
  const depthMap = {
    1: '浅度扫描：快速扫描基本漏洞，不包含严重级别的漏洞',
    2: '中度扫描：扫描所有漏洞，中等扫描速度',
    3: '深度扫描：全面扫描所有漏洞，包括严重级别漏洞'
  }
  return depthMap[depth] || '未知扫描深度'
}

// 获取风险等级颜色
const getRiskColor = (severity) => {
  const colorMap = {
    'high': '#ff6b6b',
    'medium': '#f9c74f',
    'low': '#4ecdc4'
  }
  return colorMap[severity] || '#909399'
}

// 获取漏洞数量样式类 - 修复getVulnCountClass函数缺失问题
const getVulnCountClass = (count) => {
  if (count > 10) return 'vuln-count-high'
  if (count > 0) return 'vuln-count-medium'
  return 'vuln-count-low'
}

// 导航到扫描页面 - 增强健壮性和错误处理
const goToScanPage = () => {
  try {
    // 检查当前是否已经在扫描页面，避免重复导航错误
    if (router.currentRoute.value.path === '/scan') {
      console.log('已经在扫描页面，无需重复导航')
      // 滚动到页面顶部
      window.scrollTo(0, 0)
      return
    }
    
    console.log('正在导航到扫描页面...')
    // 使用编程式导航确保正确跳转
    router.push({
      path: '/scan',
      replace: false
    })
    
    // 立即刷新DOM以确保页面切换
    nextTick(() => {
      window.scrollTo(0, 0)
      console.log('导航完成，页面已滚动到顶部')
    })
  } catch (error) {
    console.error('导航失败:', error)
    ElMessage.error('导航到扫描页面失败，请重试')
  }
}

// 查看扫描结果
const viewScanResult = (scanId) => {
  router.push({ path: '/results', query: { scanId } })
}

// 查看扫描详情
const viewScanDetail = (scanId) => {
  router.push({ path: '/scan', query: { viewId: scanId } })
}

// 查看最近结果
const viewRecentResults = () => {
  router.push('/results')
}

// 日期范围变更处理
const handleDateRangeChange = () => {
  // 根据选择的日期范围重新加载数据
  refreshDashboard()
}

// 通知命令处理
const handleNotificationCommand = (command) => {
  console.log('Notification command:', command)
  // 实现通知相关逻辑
}

// 视图模式切换处理
const handleViewModeChange = (mode) => {
  console.log('Changing view mode to:', mode)
  changeViewMode(mode)
}

// 过滤器变更处理
const handleFilterChange = (filter) => {
  console.log('Filter change:', filter)
  // 实现过滤器逻辑
}

// 视图模式切换 - 内部实现
const changeViewMode = (mode) => {
  viewMode.value = mode
  // 根据视图模式调整数据显示
  nextTick(() => {
    updateCharts()
  })
}

// 自动刷新切换
const toggleAutoRefresh = () => {
  if (autoRefreshEnabled.value) {
    startAutoRefresh()
    ElMessage.success('已开启自动刷新，每30秒更新一次数据')
  } else {
    stopAutoRefresh()
    ElMessage.info('已关闭自动刷新')
  }
}

// 开始自动刷新
const startAutoRefresh = () => {
  stopAutoRefresh() // 确保没有重复的定时器
  
  timeUntilRefresh.value = autoRefreshInterval.value
  
  // 倒计时定时器
  refreshIntervalTimer.value = setInterval(() => {
    timeUntilRefresh.value -= 1000
    if (timeUntilRefresh.value <= 0) {
      timeUntilRefresh.value = autoRefreshInterval.value
    }
  }, 1000)
  
  // 刷新定时器
  autoRefreshTimer.value = setInterval(() => {
    refreshDashboard()
  }, autoRefreshInterval.value)
}

// 停止自动刷新
const stopAutoRefresh = () => {
  if (autoRefreshTimer.value) {
    clearInterval(autoRefreshTimer.value)
    autoRefreshTimer.value = null
  }
  
  if (refreshIntervalTimer.value) {
    clearInterval(refreshIntervalTimer.value)
    refreshIntervalTimer.value = null
  }
}



// 导出仪表盘数据
const exportDashboardData = async () => {
  isRefreshing.value = true
  try {
    // 模拟导出功能
    await new Promise(resolve => setTimeout(resolve, 1500))
    
    // 准备导出数据
    const exportData = {
      timestamp: new Date().toISOString(),
      summary: {
        totalScans: totalScans.value,
        totalVulnerabilities: totalVulnerabilities.value,
        highRiskVulnerabilities: highRiskVulnerabilities.value,
        securityScore: securityScore.value,
        systemStatus: systemStatus.value
      },
      vulnerabilityDistribution: vulnerabilityDistribution.value,
      scanTrendData: scanTrendData.value,
      recentScans: recentScans.value
    }
    
    // 模拟下载
    const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' })
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `dashboard_export_${new Date().toISOString().split('T')[0]}.json`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    URL.revokeObjectURL(url)
    
    ElMessage.success('仪表盘数据已成功导出')
  } catch (error) {
    console.error('导出数据失败:', error)
    ElMessage.error('导出数据时出现错误')
  } finally {
    isRefreshing.value = false
  }
}

// 处理安全建议操作
const handleSecurityTipAction = (tip) => {
  switch (tip.id) {
    case 'tip-001':
      router.push('/results?severity=high')
      break
    case 'tip-002':
      ElMessageBox.alert('请在扫描设置页面调整扫描频率', '提示', {
        confirmButtonText: '确定',
        callback: () => {
          router.push('/settings')
        }
      })
      break
    case 'tip-003':
      ElMessage.info('安全评分趋势正在改善，继续保持良好的安全实践')
      break
    default:
      ElMessage.info(`处理安全建议: ${tip.title}`)
  }
}

// 检查服务状态
const runServiceCheck = async () => {
  isCheckingServices.value = true
  try {
    await loadServiceStatus()
    ElMessage.success('服务状态检查完成')
  } catch (error) {
    ElMessage.error('服务状态检查失败')
  } finally {
    isCheckingServices.value = false
  }
}

// 更新所有图表
const updateCharts = () => {
  initVulnerabilityChart()
  initScanTrendChart()
  initRiskTrendChart()
}

// 刷新仪表盘数据
const refreshDashboard = async () => {
  isRefreshing.value = true
  try {
    // 并行加载数据以提高性能
    await Promise.all([
      loadSystemData(),
      loadServiceStatus()
    ])
    
    // 更新最后更新时间
    lastUpdated.value = new Date()
    
    // 延迟更新图表，确保DOM已更新
    nextTick(() => {
      updateCharts()
    })
  } finally {
    isRefreshing.value = false
  }
}

// 加载系统数据
const loadSystemData = async () => {
  try {
    // 先尝试调用API获取真实数据
    try {
      console.log('正在尝试获取真实仪表盘数据...')
      // 正确传递参数格式给getDashboardStats
      const params = dateRange.value ? { startDate: dateRange.value[0], endDate: dateRange.value[1] } : {}
      const response = await apiService.getDashboardStats(params)
      
      // 使用真实API返回的数据
      if (response && response.success && response.data && response.data.metrics) {
        const metrics = response.data.metrics
        // 基本指标更新
        totalScans.value = metrics.totalScans || totalScans.value
        totalVulnerabilities.value = metrics.totalVulnerabilities || totalVulnerabilities.value
        highRiskVulnerabilities.value = metrics.highVulnerabilities || highRiskVulnerabilities.value
        mediumRiskVulnerabilities.value = metrics.mediumVulnerabilities || mediumRiskVulnerabilities.value
        lowRiskVulnerabilities.value = metrics.lowVulnerabilities || lowRiskVulnerabilities.value
        
        // 变化率更新
        scansChange.value = metrics.scansChange || scansChange.value
        vulnsChange.value = metrics.vulnerabilitiesChange || vulnsChange.value
        highRiskChange.value = metrics.highRiskChange || highRiskChange.value
        
        // 图表数据更新 - 添加数据验证，确保每个数据结构完整
        if (response.data.vulnerabilityDistribution && Array.isArray(response.data.vulnerabilityDistribution)) {
          vulnerabilityDistribution.value = response.data.vulnerabilityDistribution
        }
        if (response.data.trendData && 
            response.data.trendData.dates && 
            response.data.trendData.scans && 
            response.data.trendData.vulnerabilities) {
          scanTrendData.value = {
            dates: Array.isArray(response.data.trendData.dates) ? response.data.trendData.dates : scanTrendData.value.dates,
            scans: Array.isArray(response.data.trendData.scans) ? response.data.trendData.scans : scanTrendData.value.scans,
            vulnerabilities: Array.isArray(response.data.trendData.vulnerabilities) ? response.data.trendData.vulnerabilities : scanTrendData.value.vulnerabilities,
            highRisk: response.data.trendData.highRisk && Array.isArray(response.data.trendData.highRisk) ? response.data.trendData.highRisk : scanTrendData.value.highRisk
          }
        }
        if (response.data.trendData && 
            response.data.trendData.dates && 
            response.data.trendData.scores) {
          riskTrendData.value = {
            dates: Array.isArray(response.data.trendData.dates) ? response.data.trendData.dates : riskTrendData.value.dates,
            scores: Array.isArray(response.data.trendData.scores) ? response.data.trendData.scores : riskTrendData.value.scores,
            highRisk: response.data.trendData.highRisk && Array.isArray(response.data.trendData.highRisk) ? response.data.trendData.highRisk : riskTrendData.value.highRisk,
            mediumRisk: response.data.trendData.mediumRisk && Array.isArray(response.data.trendData.mediumRisk) ? response.data.trendData.mediumRisk : riskTrendData.value.mediumRisk,
            lowRisk: response.data.trendData.lowRisk && Array.isArray(response.data.trendData.lowRisk) ? response.data.trendData.lowRisk : riskTrendData.value.lowRisk
          }
        }
        
        // 最近扫描任务更新
        if (response.data.recentScans) {
          recentScans.value = response.data.recentScans
        }
        
        // 性能指标更新
        if (response.data.performanceMetrics) {
          performanceMetrics.value = response.data.performanceMetrics
        }
        
        ElMessage.success('已获取真实仪表盘数据')
        return
      }
    } catch (apiError) {
      console.log('API调用失败，将使用模拟数据:', apiError.message)
    }
    
    // API调用失败时，使用模拟数据并提供提示
    await new Promise(resolve => setTimeout(resolve, 800)) // 模拟网络延迟
    
    // 模拟随机更新一些数据，使仪表盘看起来更动态
    totalScans.value += Math.floor(Math.random() * 3) - 1
    const vulnChange = Math.floor(Math.random() * 5) - 2
    totalVulnerabilities.value += vulnChange
    
    // 确保风险漏洞数量合理分布
    if (vulnChange > 0) {
      const highRiskChange = Math.floor(Math.random() * Math.max(1, vulnChange))
      const mediumRiskChange = Math.floor(Math.random() * (vulnChange - highRiskChange + 1))
      const lowRiskChange = vulnChange - highRiskChange - mediumRiskChange
      
      highRiskVulnerabilities.value += highRiskChange
      mediumRiskVulnerabilities.value += mediumRiskChange
      lowRiskVulnerabilities.value += lowRiskChange
    }
    
    // 更新安全评分
    securityScore.value = Math.max(40, Math.min(95, securityScore.value + Math.floor(Math.random() * 5) - 2))
    
    // 随机更新一些扫描任务状态
    recentScans.value.forEach(scan => {
      if (scan.status === 'running') {
        scan.progress = Math.min(100, scan.progress + Math.floor(Math.random() * 15))
        if (scan.progress === 100) {
          scan.status = 'completed'
          scan.vulnerability_count = Math.floor(Math.random() * 15)
          scan.completed_at = new Date().toLocaleString()
          scan.duration = `${Math.floor(Math.random() * 30) + 5}分${Math.floor(Math.random() * 60)}秒`
        }
      }
    })
    
    // 提示用户当前使用的是模拟数据
    ElMessage.info('当前显示的是模拟数据，系统正在尝试连接后端服务')
  } catch (error) {
    console.error('加载仪表盘数据失败:', error)
    ElMessage.error('加载数据时出现错误，但系统仍可正常使用')
  }
}

// 加载服务状态
const loadServiceStatus = async () => {
  try {
    // 先尝试获取真实的服务状态数据
    try {
      console.log('正在尝试获取真实服务状态数据...')
      
      // 尝试获取API服务状态
      try {
        const healthResponse = await apiService.healthCheck()
        if (healthResponse?.status === 'healthy') {
          apiServiceStatus.value = 'running'
          systemStatus.value = 'healthy'
          
          // 更新API响应时间
          if (healthResponse.response_time) {
            apiResponseTime.value = healthResponse.response_time
          }
        } else {
          apiServiceStatus.value = 'stopped'
          systemStatus.value = 'warning'
        }
      } catch (healthError) {
        console.log('API健康检查失败:', healthError.message)
        // 不立即设置为stopped，继续尝试其他服务
      }
      
      // 尝试获取Redis状态
      try {
        const redisResponse = await apiService.checkRedisStatus()
        if (redisResponse?.status === 'healthy') {
          redisServiceStatus.value = 'running'
          // 更新Redis真实信息
          if (redisResponse.info) {
            redisInfo.value = {
              used_memory: redisResponse.info.used_memory || redisInfo.value.used_memory,
              max_memory: redisResponse.info.max_memory || redisInfo.value.max_memory,
              hit_rate: redisResponse.info.hit_rate || redisInfo.value.hit_rate
            }
            redisConnections.value = redisResponse.info.connections || redisConnections.value
          }
        } else {
          redisServiceStatus.value = 'stopped'
          systemStatus.value = 'warning'
        }
      } catch (redisError) {
        console.log('Redis状态检查失败:', redisError.message)
      }
      
      // 尝试获取Celery状态
      try {
        const celeryResponse = await apiService.checkCeleryStatus()
        if (celeryResponse?.status === 'healthy') {
          celeryServiceStatus.value = 'running'
          // 更新Celery真实信息
          if (celeryResponse.tasks) {
            celeryTasks.value = celeryResponse.tasks
          }
          if (celeryResponse.success_rate) {
            celeryTaskSuccessRate.value = celeryResponse.success_rate
          }
        } else {
          celeryServiceStatus.value = 'stopped'
          systemStatus.value = 'warning'
        }
      } catch (celeryError) {
        console.log('Celery状态检查失败:', celeryError.message)
      }
      
      console.log('服务状态检查完成')
      return // 如果成功获取了部分真实数据，就直接返回
    } catch (apiError) {
      console.log('服务状态API调用失败，将使用模拟数据:', apiError.message)
    }
    
    // API调用失败时，使用模拟数据并提供提示
    await new Promise(resolve => setTimeout(resolve, 300)) // 模拟网络延迟
    
    // 模拟健康检查数据
    apiServiceStatus.value = 'running'
    celeryServiceStatus.value = 'running'
    redisServiceStatus.value = 'running'
    streamlitServiceStatus.value = 'running'
    systemStatus.value = 'healthy'
    
    // 模拟API响应时间
    apiResponseTime.value = Math.floor(Math.random() * 30) + 30
    
    // 模拟Redis信息
    const memoryUsed = Math.random() * 200 + 20
    redisInfo.value = {
      used_memory: memoryUsed.toFixed(1),
      max_memory: '1024',
      hit_rate: (Math.random() * 5 + 95).toFixed(1) + '%'
    }
    
    // 模拟Redis连接数
    redisConnections.value = Math.floor(Math.random() * 10) + 8
    
    // 模拟Celery任务成功率
    celeryTaskSuccessRate.value = Math.floor(Math.random() * 5) + 95
    
    // 更新Celery任务状态
    const activeTasks = Math.floor(Math.random() * 5)
    const totalTasks = Math.floor(Math.random() * 30) + 10
    const completedTasks = totalTasks - activeTasks - Math.floor(Math.random() * 2)
    celeryTasks.value = {
      active: activeTasks,
      total: totalTasks,
      completed: completedTasks,
      failed: totalTasks - activeTasks - completedTasks
    }
    
    console.log('服务状态模拟数据加载成功')
  } catch (error) {
    console.error('加载服务状态失败:', error)
    // 即使出现错误，也保持界面可用
    apiServiceStatus.value = 'running'
    celeryServiceStatus.value = 'running'
    redisServiceStatus.value = 'running'
    systemStatus.value = 'healthy'
  }
}

// 初始化漏洞分布图表
const initVulnerabilityChart = () => {
  // 增强健壮性，添加多重检查 - 修复路由切换时的引用错误
  if (!vulnerabilityChartRef || !vulnerabilityChartRef.value || !vulnerabilityChartRef.value.parentNode) {
    console.warn('漏洞分布图表引用未定义或DOM结构不完整')
    return
  }
  
  // 安全销毁现有图表
  if (vulnerabilityChartInstance && vulnerabilityChartInstance.value && typeof vulnerabilityChartInstance.value.dispose === 'function') {
    try {
      vulnerabilityChartInstance.value.dispose()
      vulnerabilityChartInstance.value = null
    } catch (error) {
      console.warn('销毁现有图表时出错:', error)
      vulnerabilityChartInstance.value = null
    }
  }
  
  try {
    // 创建新图表
    vulnerabilityChartInstance.value = echarts.init(vulnerabilityChartRef.value)
    
    // 添加自动销毁保护
    vulnerabilityChartInstance.value._dom._chart_ = vulnerabilityChartInstance
  } catch (error) {
    console.warn('初始化漏洞分布图表时出错:', error)
    vulnerabilityChartInstance.value = null
    return
  }
  
  // 根据选择的图表类型配置
  let option
  
  if (chartType1.value === 'pie') {
    // 饼图配置
    option = {
      tooltip: {
        trigger: 'item',
        backgroundColor: 'rgba(255, 255, 255, 0.95)',
        borderColor: '#d9d9d9',
        borderRadius: 8,
        textStyle: {
          color: '#333'
        },
        formatter: '{b}: {c} ({d}%)<br/>占总量的 {d}%'
      },
      legend: {
        orient: 'vertical',
        left: 'left',
        top: 'center',
        textStyle: {
          color: '#666'
        },
        animationDelay: (idx) => idx * 100
      },
      series: [
        {
          name: '漏洞类型',
          type: 'pie',
          radius: ['40%', '70%'],
          center: ['60%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 10,
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            show: false,
            position: 'center'
          },
          emphasis: {
            label: {
              show: true,
              fontSize: '18',
              fontWeight: 'bold',
              formatter: '{b}\n{d}%'
            },
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          },
          labelLine: {
            show: false
          },
          data: vulnerabilityDistribution.value || [],
          animationType: 'scale',
          animationEasing: 'elasticOut',
          animationDelay: (idx) => idx * 100
        }
      ],
      color: (vulnerabilityDistribution.value || []).map(item => item.color || '#909399')
    }
  } else {
    // 柱状图配置
    option = {
      tooltip: {
        trigger: 'axis',
        backgroundColor: 'rgba(255, 255, 255, 0.95)',
        borderColor: '#d9d9d9',
        borderRadius: 8,
        textStyle: {
          color: '#333'
        }
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: (vulnerabilityDistribution.value || []).map(item => item.name || ''),
        axisTick: {
          alignWithLabel: true
        },
        axisLabel: {
          rotate: 45,
          color: '#666'
        }
      },
      yAxis: {
        type: 'value',
        axisLabel: {
          color: '#666'
        }
      },
      series: [
        {
          name: '漏洞数量',
          type: 'bar',
          barWidth: '60%',
          data: (vulnerabilityDistribution.value || []).map((item, index) => ({
            value: item.value,
            itemStyle: {
              color: item.color || new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: `rgba(${255 - index * 30}, ${100 + index * 20}, 100, 1)` },
                { offset: 1, color: `rgba(${200 - index * 25}, ${50 + index * 15}, 80, 0.8)` }
              ])
            }
          })),
          animationDelay: (idx) => idx * 100
        }
      ],
      animationEasing: 'elasticOut'
    }
  }
  
  // 设置图表配置
  if (vulnerabilityChartInstance.value) {
    vulnerabilityChartInstance.value.setOption(option)
  }
  
  // 添加响应式调整，使用统一的handleResize函数
  // 注意：不要在这里单独添加resize事件监听，统一在onMounted中处理
  // 确保在resize前进行安全检查
  vulnerabilityChartInstance.value._resizeHandler = handleResize
}







// 初始化扫描趋势图表
const initScanTrendChart = () => {
  // 增强健壮性，添加多重检查 - 修复路由切换时的引用错误
  if (!scanTrendChartRef || !scanTrendChartRef.value || !scanTrendChartRef.value.parentNode) {
    console.warn('扫描趋势图表引用未定义或DOM结构不完整')
    return
  }
  
  // 安全销毁现有图表
  if (scanTrendChartInstance && scanTrendChartInstance.value && typeof scanTrendChartInstance.value.dispose === 'function') {
    try {
      scanTrendChartInstance.value.dispose()
      scanTrendChartInstance.value = null
    } catch (error) {
      console.warn('销毁现有图表时出错:', error)
      scanTrendChartInstance.value = null
    }
  }
  
  try {
    // 创建新图表
    scanTrendChartInstance.value = echarts.init(scanTrendChartRef.value)
    
    // 添加自动销毁保护
    scanTrendChartInstance.value._dom._chart_ = scanTrendChartInstance
  } catch (error) {
    console.warn('初始化扫描趋势图表时出错:', error)
    scanTrendChartInstance.value = null
    return
  }
  
  // 图表配置
  const option = {
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(255, 255, 255, 0.95)',
      borderColor: '#d9d9d9',
      borderRadius: 8,
      textStyle: {
        color: '#333'
      },
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985'
        }
      }
    },
    legend: {
      data: ['完成扫描数', '发现漏洞数'],
      top: 10,
      textStyle: {
        color: '#666'
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: [
      {
        type: 'category',
        boundaryGap: false,
        data: scanTrendData.value?.dates || [],
        axisLabel: {
          color: '#666'
        },
        axisLine: {
          lineStyle: {
            color: '#e0e0e0'
          }
        }
      }
    ],
    yAxis: [
      {
        type: 'value',
        name: '数量',
        nameTextStyle: {
          color: '#666'
        },
        axisLabel: {
          color: '#666',
          formatter: '{value}'
        },
        axisLine: {
          lineStyle: {
            color: '#e0e0e0'
          }
        },
        splitLine: {
          lineStyle: {
            color: '#f0f0f0'
          }
        }
      }
    ],
    series: [
      {
        name: '完成扫描数',
        type: 'line',
        stack: '总量',
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(102, 126, 234, 0.8)' },
            { offset: 1, color: 'rgba(102, 126, 234, 0.1)' }
          ])
        },
        emphasis: {
          focus: 'series'
        },
        lineStyle: {
          width: 3,
          color: '#667eea'
        },
        itemStyle: {
          color: '#667eea',
          borderColor: '#fff',
          borderWidth: 2
        },
        data: scanTrendData.value?.scans || [],
        animationDuration: 1000,
        animationEasing: 'cubicInOut'
      },
      {
        name: '发现漏洞数',
        type: 'line',
        stack: '总量',
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(255, 77, 79, 0.8)' },
            { offset: 1, color: 'rgba(255, 77, 79, 0.1)' }
          ])
        },
        emphasis: {
          focus: 'series'
        },
        lineStyle: {
          width: 3,
          color: '#ff4d4f'
        },
        itemStyle: {
          color: '#ff4d4f',
          borderColor: '#fff',
          borderWidth: 2
        },
        data: scanTrendData.value?.vulnerabilities || [],
        animationDuration: 1000,
        animationEasing: 'cubicInOut',
        animationDelay: 200
      }
    ]
  }
  
  // 设置图表配置
  if (scanTrendChartInstance.value) {
    scanTrendChartInstance.value.setOption(option)
  }
}

// 新增：初始化风险趋势图表
const initRiskTrendChart = () => {
  // 增强健壮性，添加多重检查 - 修复路由切换时的引用错误
  if (!riskTrendChartRef || !riskTrendChartRef.value || !riskTrendChartRef.value.parentNode) {
    console.warn('风险趋势图表引用未定义或DOM结构不完整')
    return
  }
  
  // 安全销毁现有图表
  if (riskTrendChartInstance && riskTrendChartInstance.value && typeof riskTrendChartInstance.value.dispose === 'function') {
    try {
      riskTrendChartInstance.value.dispose()
      riskTrendChartInstance.value = null
    } catch (error) {
      console.warn('销毁现有图表时出错:', error)
      riskTrendChartInstance.value = null
    }
  }
  
  try {
    // 创建新图表
    riskTrendChartInstance.value = echarts.init(riskTrendChartRef.value)
    
    // 添加自动销毁保护
    riskTrendChartInstance.value._dom._chart_ = riskTrendChartInstance
  } catch (error) {
    console.warn('初始化风险趋势图表时出错:', error)
    riskTrendChartInstance.value = null
    return
  }
  
  // 图表配置
  const option = {
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(255, 255, 255, 0.95)',
      borderColor: '#d9d9d9',
      borderRadius: 8,
      textStyle: {
        color: '#333'
      },
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985'
        }
      }
    },
    legend: {
      data: ['高风险', '中风险', '低风险'],
      top: 10,
      textStyle: {
        color: '#666'
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: [
      {
        type: 'category',
        boundaryGap: false,
        data: riskTrendData.value?.dates || [],
        axisLabel: {
          color: '#666'
        },
        axisLine: {
          lineStyle: {
            color: '#e0e0e0'
          }
        }
      }
    ],
    yAxis: [
      {
        type: 'value',
        name: '漏洞数量',
        nameTextStyle: {
          color: '#666'
        },
        axisLabel: {
          color: '#666',
          formatter: '{value}'
        },
        axisLine: {
          lineStyle: {
            color: '#e0e0e0'
          }
        },
        splitLine: {
          lineStyle: {
            color: '#f0f0f0'
          }
        }
      }
    ],
    series: [
      {
        name: '高风险',
        type: 'line',
        stack: '风险总量',
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(239, 68, 68, 0.8)' },
            { offset: 1, color: 'rgba(239, 68, 68, 0.1)' }
          ])
        },
        emphasis: {
          focus: 'series'
        },
        lineStyle: {
          width: 3,
          color: '#ef4444'
        },
        itemStyle: {
          color: '#ef4444',
          borderColor: '#fff',
          borderWidth: 2
        },
        data: riskTrendData.value?.highRisk || [],
        animationDuration: 1000,
        animationEasing: 'cubicInOut'
      },
      {
        name: '中风险',
        type: 'line',
        stack: '风险总量',
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(245, 158, 11, 0.8)' },
            { offset: 1, color: 'rgba(245, 158, 11, 0.1)' }
          ])
        },
        emphasis: {
          focus: 'series'
        },
        lineStyle: {
          width: 3,
          color: '#f59e0b'
        },
        itemStyle: {
          color: '#f59e0b',
          borderColor: '#fff',
          borderWidth: 2
        },
        data: riskTrendData.value?.mediumRisk || [],
        animationDuration: 1000,
        animationEasing: 'cubicInOut',
        animationDelay: 200
      },
      {
        name: '低风险',
        type: 'line',
        stack: '风险总量',
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(16, 185, 129, 0.8)' },
            { offset: 1, color: 'rgba(16, 185, 129, 0.1)' }
          ])
        },
        emphasis: {
          focus: 'series'
        },
        lineStyle: {
          width: 3,
          color: '#10b981'
        },
        itemStyle: {
          color: '#10b981',
          borderColor: '#fff',
          borderWidth: 2
        },
        data: riskTrendData.value?.lowRisk || [],
        animationDuration: 1000,
        animationEasing: 'cubicInOut',
        animationDelay: 400
      }
    ]
  }
  
  // 设置图表配置
  if (riskTrendChartInstance.value) {
    riskTrendChartInstance.value.setOption(option)
  }
}

// 窗口大小改变时重新调整图表大小 - 增强防御性编程
const handleResize = () => {
  // 安全调整漏洞分布图表
  try {
    if (vulnerabilityChartInstance && 
        vulnerabilityChartInstance.value && 
        typeof vulnerabilityChartInstance.value.resize === 'function' &&
        vulnerabilityChartInstance.value._dom &&
        document.body.contains(vulnerabilityChartInstance.value._dom)) {
      vulnerabilityChartInstance.value.resize()
    }
  } catch (error) {
    console.warn('调整漏洞分布图表大小时出错:', error)
  }
  
  // 安全调整扫描趋势图表
  try {
    if (scanTrendChartInstance && 
        scanTrendChartInstance.value && 
        typeof scanTrendChartInstance.value.resize === 'function' &&
        scanTrendChartInstance.value._dom &&
        document.body.contains(scanTrendChartInstance.value._dom)) {
      scanTrendChartInstance.value.resize()
    }
  } catch (error) {
    console.warn('调整扫描趋势图表大小时出错:', error)
  }
  
  // 安全调整风险趋势图表
  try {
    if (riskTrendChartInstance && 
        riskTrendChartInstance.value && 
        typeof riskTrendChartInstance.value.resize === 'function' &&
        riskTrendChartInstance.value._dom &&
        document.body.contains(riskTrendChartInstance.value._dom)) {
      riskTrendChartInstance.value.resize()
    }
  } catch (error) {
    console.warn('调整风险趋势图表大小时出错:', error)
  }
  
  // 安全调整概览趋势图表
  try {
    if (overviewTrendChartInstance && 
        overviewTrendChartInstance.value && 
        typeof overviewTrendChartInstance.value.resize === 'function' &&
        overviewTrendChartInstance.value._dom &&
        document.body.contains(overviewTrendChartInstance.value._dom)) {
      overviewTrendChartInstance.value.resize()
    }
  } catch (error) {
    console.warn('调整概览趋势图表大小时出错:', error)
  }
}

// 组件挂载时加载数据 - 增强防御性编程
onMounted(() => {
  try {
    loadSystemData()
    loadServiceStatus()
    
    // 延迟初始化图表，确保DOM已更新
    const chartInitTimer = setTimeout(() => {
      nextTick(() => {
        // 检查组件是否仍然挂载
          if (vulnerabilityChartRef && vulnerabilityChartRef.value) {
            initVulnerabilityChart()
          }
        if (scanTrendChartRef && scanTrendChartRef.value) {
          initScanTrendChart()
        }
        if (riskTrendChartRef && riskTrendChartRef.value) {
          initRiskTrendChart()
        }
        if (overviewTrendChartRef && overviewTrendChartRef.value) {
          initOverviewTrendChart()
        }
      })
    }, 100) // 小延迟确保DOM完全渲染
    
    // 监听窗口大小变化
    window.addEventListener('resize', handleResize)
    
    // 启动自动刷新
    if (autoRefreshEnabled.value) {
      startAutoRefresh()
    }
    
    // 将timer ID保存到ref中以便在onUnmounted中清理
    chartInitTimerRef.value = chartInitTimer
  } catch (error) {
    console.error('组件挂载时出错:', error)
  }
})

// 增强的图表实例管理 - 修复路由切换时的内存泄漏和引用错误
const safelyDisposeChart = (chartInstance) => {
  if (!chartInstance || !chartInstance.value) {
    return
  }
  
  try {
    // 检查实例是否有效且可销毁
    if (typeof chartInstance.value.dispose === 'function') {
      chartInstance.value.dispose()
    }
  } catch (error) {
    console.warn('销毁图表实例时出错:', error)
  } finally {
    // 强制设置为null
    chartInstance.value = null
  }
}

// 组件卸载时清理资源
onUnmounted(() => {
  try {
    // 移除窗口大小变化监听器
    window.removeEventListener('resize', handleResize)
    
    // 移除窗口错误监听器
    if (windowErrorHandler) {
      window.removeEventListener('error', windowErrorHandler)
      windowErrorHandler = null
    }
    
    // 清理初始化定时器
    if (chartInitTimerRef && chartInitTimerRef.value) {
      clearTimeout(chartInitTimerRef.value)
      chartInitTimerRef.value = null
    }
    
    // 停止所有定时器 - 确保清理所有可能的定时器
    // 1. refreshTimer (在setupAutoRefresh中使用)
    if (refreshTimer && typeof refreshTimer === 'number') {
      clearInterval(refreshTimer)
      refreshTimer = null
    }
    
    // 2. autoRefreshTimer (在startAutoRefresh中使用)
    if (autoRefreshTimer && autoRefreshTimer.value) {
      clearInterval(autoRefreshTimer.value)
      autoRefreshTimer.value = null
    }
    
    // 3. refreshIntervalTimer (在startAutoRefresh中使用)
    if (refreshIntervalTimer && refreshIntervalTimer.value) {
      clearInterval(refreshIntervalTimer.value)
      refreshIntervalTimer.value = null
    }
    
    // 安全销毁所有图表实例
    safelyDisposeChart(vulnerabilityChartInstance)
    safelyDisposeChart(scanTrendChartInstance)
    safelyDisposeChart(riskTrendChartInstance)
    safelyDisposeChart(overviewTrendChartInstance)
    
    // 安全清理DOM引用
    if (vulnerabilityChartRef) vulnerabilityChartRef.value = null
    if (scanTrendChartRef) scanTrendChartRef.value = null
    if (riskTrendChartRef) riskTrendChartRef.value = null
    if (overviewTrendChartRef) overviewTrendChartRef.value = null
    
    // 释放数据引用，帮助垃圾回收
    try {
      if (scanTrendData) scanTrendData.value = { dates: [], scans: [], vulnerabilities: [] }
      if (riskTrendData) riskTrendData.value = { dates: [], highRisk: [], mediumRisk: [], lowRisk: [] }
    } catch (e) {
      console.warn('清理数据引用时出错:', e)
    }
  } catch (error) {
    console.error('组件卸载时清理资源出错:', error)
  }
})
</script>



<style scoped>
.dashboard-container {
  padding: 0;
  background: transparent;
  min-height: calc(100vh - 128px);
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  position: relative;
  z-index: 2;
}

.page-header {
  margin-bottom: 30px;
  text-align: center;
  position: relative;
  padding-top: 40px;
}

.title-badge {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
  animation: float 3s ease-in-out infinite;
}

.badge-icon {
  font-size: 28px;
  color: white;
}

.page-title {
  font-size: 24px;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 12px;
  text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.08);
  position: relative;
  display: inline-block;
  line-height: 1.3;
}

.page-title::after {
  content: '';
  position: absolute;
  bottom: -8px;
  left: 50%;
  transform: translateX(-50%);
  width: 60px;
  height: 3px;
  background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
  border-radius: 1.5px;
}

.page-description {
  font-size: 16px;
  color: #7f8c8d;
  max-width: 800px;
  margin: 0 auto;
  line-height: 1.6;
}

.quick-actions {
  display: flex;
  gap: 16px;
  margin-bottom: 30px;
  justify-content: center;
  flex-wrap: wrap;
}

.primary-action {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  padding: 12px 24px;
  font-weight: 600;
  font-size: 16px;
  border-radius: 8px;
  transition: all 0.3s ease;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.primary-action:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(102, 126, 234, 0.4);
}

.secondary-action {
  background: #ffffff;
  border: 2px solid #667eea;
  color: #667eea;
  padding: 10px 20px;
  font-weight: 500;
  border-radius: 8px;
  transition: all 0.3s ease;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.secondary-action:hover {
  background: #f8f9ff;
  border-color: #764ba2;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
}

.btn-icon {
  font-size: 18px;
}

/* 指标卡片 */
.metrics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
  margin-bottom: 24px;
}

.metric-card {
  transition: all 0.3s ease;
  overflow: hidden;
  position: relative;
  background: #ffffff;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  border: 1px solid #e2e8f0;
  backdrop-filter: blur(10px);
}

.metric-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: linear-gradient(90deg, #4f46e5 0%, #3b82f6 100%);
}

.metric-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 20px rgba(0, 0, 0, 0.15);
}

.metric-content {
  display: flex;
  align-items: center;
  padding: 24px;
}

.metric-icon {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 16px;
  background: rgba(79, 70, 229, 0.1);
  transition: all 0.3s ease;
}

.metric-card:hover .metric-icon {
  transform: scale(1.1);
}

.icon-scan {
  color: #3b82f6;
  font-size: 28px;
}

.icon-vuln {
  color: #ef4444;
  font-size: 28px;
}

.icon-risk {
  color: #f97316;
  font-size: 28px;
}

.icon-system {
  color: #10b981;
  font-size: 28px;
}

.metric-info {
  flex: 1;
}

.metric-title {
  font-size: 14px;
  color: #6b7280;
  margin: 0 0 8px 0;
  font-weight: normal;
}

.metric-value {
  font-size: 24px;
  font-weight: 700;
  color: #1f2937;
  margin: 0 0 6px 0;
  animation: countUp 1s ease-out;
  line-height: 1.2;
}

.metric-change {
  font-size: 12px;
  padding: 2px 8px;
  border-radius: 12px;
  background-color: #f3f4f6;
}

.metric-change.positive {
  color: #10b981;
  background-color: rgba(16, 185, 129, 0.1);
}

.metric-change.negative {
  color: #ef4444;
  background-color: rgba(239, 68, 68, 0.1);
}

.system-status-indicator {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-left: 8px;
  animation: pulse 2s infinite;
}

.system-status-indicator.healthy {
  background-color: #10b981;
}

.system-status-indicator.warning {
  background-color: #f59e0b;
  animation: pulse-warning 2s infinite;
}

.system-status-indicator.critical {
  background-color: #ef4444;
  animation: pulse-error 2s infinite;
}

/* 图表区域 */
.charts-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(480px, 1fr));
  gap: 24px;
  margin-bottom: 28px;
  margin-top: 8px;
}

.chart-card {
  transition: all 0.3s ease;
  background: #ffffff;
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  border: none;
  overflow: hidden;
}

.chart-card:hover {
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
  transform: translateY(-2px);
}

.card-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: 16px;
  color: #374151;
  padding: 16px 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-radius: 12px 12px 0 0;
}

.chart-container {
  height: 320px;
  padding: 20px;
  background: #ffffff;
  border-radius: 0 0 12px 12px;
}

.view-all-btn {
  margin-left: auto;
  background: #ffffff;
  color: #667eea;
  border: none;
  transition: all 0.3s ease;
}

.view-all-btn:hover {
  background: #f8f9ff;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
}

/* 最近扫描任务 */
.recent-scans-card {
  margin-bottom: 28px;
  background: #ffffff;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  border: 1px solid #e2e8f0;
  overflow: hidden;
  transition: all 0.3s ease;
  backdrop-filter: blur(10px);
}

.recent-scans-card:hover {
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
  transform: translateY(-2px);
}

.recent-scans-content {
  padding: 16px 20px;
}

.recent-scans-table {
  font-size: 14px;
  border-radius: 8px;
  overflow: hidden;
}

.scan-row {
  transition: all 0.3s ease;
}

.scan-row:hover {
  background-color: #f8f9ff;
  transform: translateX(4px);
}

.recent-scans-table .el-table__header th {
  background-color: #f9fafb;
  font-weight: 500;
  color: #374151;
  border-bottom: 2px solid #e5e7eb;
}

.high-count {
  color: #ef4444;
  font-weight: 500;
}

.normal-count {
  color: #374151;
}

/* 成功率样式类 */
.high-success {
  color: #10b981;
  font-weight: 600;
}

.medium-success {
  color: #f59e0b;
  font-weight: 500;
}

.low-success {
  color: #ef4444;
  font-weight: 500;
}

.status-tag {
  padding: 4px 12px;
  border-radius: 16px;
  font-size: 12px;
  font-weight: 500;
}

.target-cell {
  display: flex;
  align-items: center;
  gap: 6px;
}

.url-icon {
  font-size: 14px;
  color: #667eea;
}

.target-url {
  color: #374151;
  font-weight: 500;
  word-break: break-all;
}

.action-button {
  transition: all 0.3s ease;
  border-radius: 6px;
  padding: 4px 12px;
}

.action-button:hover {
  transform: translateY(-1px);
}

.empty-scans {
  padding: 40px 0;
  text-align: center;
}

/* 系统服务状态 */
.system-status-card {
  margin-bottom: 28px;
  background: #ffffff;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  border: 1px solid #e2e8f0;
  overflow: hidden;
  transition: all 0.3s ease;
  backdrop-filter: blur(10px);
}

.system-status-card:hover {
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
  transform: translateY(-2px);
}

.service-status-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px;
  padding: 20px;
}

.service-item {
  display: flex;
  align-items: center;
  padding: 16px;
  border-radius: 12px;
  background-color: #f9fafb;
  transition: all 0.3s ease;
  border: 2px solid transparent;
  position: relative;
  overflow: hidden;
}

.service-item::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 4px;
  height: 100%;
  background: transparent;
  transition: background 0.3s ease;
}

.service-item.running {
  border-color: #10b981;
  background-color: rgba(16, 185, 129, 0.05);
}

.service-item.running::before {
  background: #10b981;
}

.service-item.stopped {
  border-color: #ef4444;
  background-color: rgba(239, 68, 68, 0.05);
}

.service-item.stopped::before {
  background: #ef4444;
}

.service-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
}

.service-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 16px;
  font-size: 24px;
  background-color: white;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}

.service-item:hover .service-icon {
  transform: scale(1.1);
}

.service-info h4 {
  font-size: 16px;
  color: #1f2937;
  margin: 0 0 4px 0;
}

.service-status {
  font-size: 14px;
  font-weight: 600;
  margin: 0 0 2px 0;
}

.service-item.running .service-status {
  color: #10b981;
}

.service-item.stopped .service-status {
  color: #ef4444;
}

.service-url,
.service-details {
  font-size: 12px;
  color: #6b7280;
  margin: 0;
}

/* 动画效果 */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes float {
  0% {
    transform: translate(-50%, 0);
  }
  50% {
    transform: translate(-50%, -8px);
  }
  100% {
    transform: translate(-50%, 0);
  }
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
  }
  70% {
    box-shadow: 0 0 0 8px rgba(16, 185, 129, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
  }
}

@keyframes pulse-warning {
  0% {
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.7);
  }
  70% {
    box-shadow: 0 0 0 8px rgba(245, 158, 11, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0);
  }
}

@keyframes pulse-error {
  0% {
    box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
  }
  70% {
    box-shadow: 0 0 0 8px rgba(239, 68, 68, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
  }
}

@keyframes countUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.metric-card, .chart-card, .recent-scans-card, .system-status-card {
  animation: fadeIn 0.5s ease;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .charts-row {
    grid-template-columns: 1fr;
  }
  
  .chart-container {
    height: 300px;
  }
}

@media (max-width: 768px) {
  .dashboard-container {
    padding: 12px;
  }
  
  .page-header {
    padding-top: 30px;
  }
  
  .title-badge {
    width: 50px;
    height: 50px;
  }
  
  .badge-icon {
    font-size: 24px;
  }
  
  .page-title {
    font-size: 24px;
  }
  
  .card-header {
    padding: 12px 16px;
  }
  
  .metrics-grid {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  
  .quick-actions {
    flex-direction: column;
    gap: 12px;
  }
  
  .chart-container {
    height: 250px;
    padding: 16px;
  }
  
  .service-status-grid {
    grid-template-columns: 1fr;
    padding: 16px;
  }
  
  .recent-scans-content {
    padding: 10px 16px;
  }
  
  .recent-scans-table {
    font-size: 12px;
  }
  
  .recent-scans-table .el-table__header {
    display: none;
  }
  
  .recent-scans-table .el-table__body-wrapper {
    overflow-x: auto;
  }
}

@media (max-width: 480px) {
  .metric-content {
    flex-direction: column;
    text-align: center;
    gap: 12px;
  }
  
  .metric-icon {
    margin-right: 0;
  }
  
  .metric-value {
    font-size: 28px;
  }
  
  .service-item {
    flex-direction: column;
    text-align: center;
    gap: 12px;
  }
  
  .service-icon {
    margin-right: 0;
  }
}

/* 滚动条样式 */
.recent-scans-table .el-table__body-wrapper::-webkit-scrollbar {
  height: 6px;
}

.recent-scans-table .el-table__body-wrapper::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.recent-scans-table .el-table__body-wrapper::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.recent-scans-table .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
  background: #a1a1a1;
}
/* 统计卡片精美化样式 */
.metrics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
  margin-top: 24px;
}

.metric-card {
  border: none;
  border-radius: 12px;
  overflow: hidden;
  transition: all 0.3s ease;
}

.metric-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}

.metric-bg-decoration {
  position: absolute;
  top: 0;
  right: 0;
  width: 100px;
  height: 100px;
  opacity: 0.1;
  border-radius: 50%;
}

.success-bg {
  background-color: var(--el-color-success);
  transform: translate(30%, -30%);
}

.warning-bg {
  background-color: var(--el-color-warning);
  transform: translate(30%, -30%);
}

.danger-bg {
  background-color: var(--el-color-danger);
  transform: translate(30%, -30%);
}

.info-bg {
  background-color: var(--el-color-info);
  transform: translate(30%, -30%);
}

.metric-footer-gradient {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 4px;
  border-radius: 0 0 12px 12px;
}

.success-gradient {
  background: linear-gradient(90deg, var(--el-color-success-light-3), var(--el-color-success));
}

.warning-gradient {
  background: linear-gradient(90deg, var(--el-color-warning-light-3), var(--el-color-warning));
}

.danger-gradient {
  background: linear-gradient(90deg, var(--el-color-danger-light-3), var(--el-color-danger));
}

.info-gradient {
  background: linear-gradient(90deg, var(--el-color-info-light-3), var(--el-color-info));
}

.metric-icon-container {
  background-color: rgba(255, 255, 255, 0.9);
  border: 2px solid var(--el-border-color);
}

.metric-icon-container.success {
  color: var(--el-color-success);
  border-color: var(--el-color-success-light-3);
  background-color: rgba(240, 249, 235, 0.8);
}

.metric-icon-container.warning {
  color: var(--el-color-warning);
  border-color: var(--el-color-warning-light-3);
  background-color: rgba(253, 246, 236, 0.8);
}

.metric-icon-container.danger {
  color: var(--el-color-danger);
  border-color: var(--el-color-danger-light-3);
  background-color: rgba(254, 240, 240, 0.8);
}

.metric-icon-container.info {
  color: var(--el-color-info);
  border-color: var(--el-color-info-light-3);
  background-color: rgba(244, 244, 245, 0.8);
}

/* 评分样式 */
.score-progress {
  margin-top: 8px;
}

.score-progress-bar .el-progress-bar__outer {
  height: 6px;
  border-radius: 3px;
  background-color: #f0f2f5;
}

.score-progress-bar .el-progress-bar__inner {
  border-radius: 3px;
}

/* 等级样式 */
.grade-excellent {
  color: var(--el-color-success);
  background-color: rgba(240, 249, 235, 0.6);
}

.grade-good {
  color: #67c23a;
  background-color: rgba(240, 249, 235, 0.4);
}

.grade-fair {
  color: var(--el-color-warning);
  background-color: rgba(253, 246, 236, 0.6);
}

.grade-poor {
  color: #e6a23c;
  background-color: rgba(253, 246, 236, 0.4);
}

.grade-critical {
  color: var(--el-color-danger);
  background-color: rgba(254, 240, 240, 0.6);
}

/* 图表区域精美化 */
.charts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
  gap: 24px;
  margin-top: 32px;
}

.chart-card {
  border-radius: 12px;
  border: 1px solid var(--el-border-color);
  transition: all 0.3s ease;
}

.chart-card:hover {
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0;
}

.header-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--el-text-color-primary);
  margin-left: 8px;
}

.chart-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .metrics-grid {
    grid-template-columns: 1fr;
  }
  
  .charts-grid {
    grid-template-columns: 1fr;
  }
}

/* 动画效果 */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.metric-card {
  animation: fadeInUp 0.5s ease-out;
}

.metric-card:nth-child(2) {
  animation-delay: 0.1s;
}

.metric-card:nth-child(3) {
  animation-delay: 0.2s;
}

.metric-card:nth-child(4) {
  animation-delay: 0.3s;
}

/* 顶部工具栏样式优化 */
.top-toolbar {
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  border-radius: 16px;
  padding: 16px 24px;
  margin-bottom: 24px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
  border: 1px solid #e2e8f0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* 工具栏按钮组优化 */
.toolbar-left,
.toolbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* 优化选择器样式 */
.el-date-editor,
.el-select {
  border-radius: 8px;
  border: 1px solid #e2e8f0;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.el-date-editor:hover,
.el-select:hover {
  border-color: #667eea;
}

.el-date-editor:focus-within,
.el-select:focus-within {
  border-color: #667eea;
  box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
}

/* 优化图标按钮 */
.el-button--icon {
  border-radius: 8px;
  transition: all 0.2s ease;
}

.el-button--icon:hover {
  background: #f8fafc;
  transform: translateY(-1px);
}

/* 优化分隔线 */
.toolbar-divider {
  width: 1px;
  height: 24px;
  background: #e2e8f0;
  margin: 0 8px;
}

.page-title {
  font-size: 20px;
  font-weight: 700;
  background: linear-gradient(45deg, #667eea, #764ba2);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* 系统状态栏样式优化 */
.system-status-bar {
  background-color: #fafafa;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 24px;
  border: 1px solid var(--el-border-color);
}

.status-indicator {
  padding: 4px 12px;
  border-radius: 16px;
  font-size: 14px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.status-indicator.normal {
  background-color: rgba(240, 249, 235, 0.8);
  color: var(--el-color-success);
}

.status-indicator.warning {
  background-color: rgba(253, 246, 236, 0.8);
  color: var(--el-color-warning);
}

.status-indicator.error {
  background-color: rgba(254, 240, 240, 0.8);
  color: var(--el-color-danger);
}

.resource-item {
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 12px;
  margin-left: 8px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.resource-item.safe {
  background-color: rgba(240, 249, 235, 0.6);
  color: var(--el-color-success);
}

.resource-item.warning {
  background-color: rgba(253, 246, 236, 0.6);
  color: var(--el-color-warning);
}

.resource-item.danger {
  background-color: rgba(254, 240, 240, 0.6);
  color: var(--el-color-danger);
}

/* 工具提示样式优化 */
.el-tooltip__popper {
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  border: none;
}

/* 优化新建扫描按钮样式 */
.scan-btn {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  padding: 10px 20px;
  font-size: 16px;
  font-weight: 600;
  border-radius: 8px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}

.scan-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(102, 126, 234, 0.6);
  background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
}

.scan-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 8px rgba(102, 126, 234, 0.4);
}

.scan-btn .el-icon {
  margin-right: 6px;
  font-size: 18px;
}

/* 安全态势概览卡片样式优化 */
.security-overview-card {
  margin-bottom: 24px;
}

.overview-card {
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  border: none;
  background: white;
}

.overview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 24px;
  border-bottom: 1px solid #e2e8f0;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
}

.overview-title {
  display: flex;
  align-items: center;
  gap: 8px;
}

.overview-title h3 {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  color: #1e293b;
  background: linear-gradient(45deg, #667eea, #764ba2);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.overview-icon {
  color: #667eea;
  font-size: 22px;
}

.overview-range-select {
  width: 140px;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.overview-content {
  padding: 0;
}

.overview-metrics {
  display: flex;
  justify-content: space-between;
  padding: 20px;
  gap: 16px;
  flex-wrap: wrap;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
}

.overview-metric {
  text-align: center;
  flex: 1;
  min-width: 160px;
  padding: 16px;
  background: white;
  border-radius: 12px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  border: 1px solid #e2e8f0;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  position: relative;
  overflow: hidden;
}

.overview-metric::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 4px;
  height: 100%;
  background: linear-gradient(180deg, #667eea 0%, #764ba2 100%);
  border-radius: 4px 0 0 4px;
}

.overview-metric:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(102, 126, 234, 0.2);
  border-color: #667eea;
}

.overview-metric .metric-value {
  font-size: 28px;
  font-weight: 700;
  margin-bottom: 6px;
  color: #1e293b;
  animation: countUp 1s ease-out;
  font-family: 'Inter', sans-serif;
  line-height: 1.2;
}

.overview-metric .metric-label {
  font-size: 13px;
  color: #64748b;
  margin-bottom: 8px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

.overview-metric .metric-change {
  font-size: 12px;
  padding: 3px 8px;
  border-radius: 20px;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-weight: 600;
  transition: all 0.2s ease;
}

.overview-metric .metric-change.positive {
  background-color: rgba(16, 185, 129, 0.1);
  color: #059669;
}

.overview-metric .metric-change.positive:hover {
  background-color: rgba(16, 185, 129, 0.2);
}

.overview-metric .metric-change.negative {
  background-color: rgba(239, 68, 68, 0.1);
  color: #dc2626;
}

.overview-metric .metric-change.negative:hover {
  background-color: rgba(239, 68, 68, 0.2);
}

.overview-trend-chart {
  height: 280px;
  padding: 0 24px 20px;
  background: white;
}

/* 关键指标卡片样式统一 */
.metrics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
  margin-bottom: 24px;
}

.metric-card {
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
  border: none;
  background: white;
  transition: all 0.3s ease;
}

.metric-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

.metric-card-header {
  padding: 16px 20px;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
  border-bottom: 1px solid #e2e8f0;
}

.metric-card-content {
  padding: 20px;
}

/* 漏洞列表样式优化 */
.recent-scans-card {
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  border: none;
  background: white;
  margin-bottom: 24px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 24px;
  border-bottom: 1px solid #e2e8f0;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
}

.header-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.header-icon {
  color: #667eea;
  font-size: 20px;
}

.header-title {
  font-size: 18px;
  font-weight: 600;
  color: #1e293b;
  margin: 0;
  background: linear-gradient(45deg, #667eea, #764ba2);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* 优化表格样式 */
.el-table {
  border-radius: 0 0 12px 12px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.el-table th {
  background: #f8fafc;
  font-weight: 600;
  color: #334155;
  padding: 14px 20px;
  border-bottom: 1px solid #e2e8f0;
  font-size: 14px;
}

.el-table td {
  padding: 14px 20px;
  border-bottom: 1px solid #f1f5f9;
  font-size: 14px;
  line-height: 1.5;
}

.el-table__row:hover {
  background: #f8fafc;
  transform: translateY(-1px);
  transition: all 0.2s ease;
}

/* 表格行分隔优化 */
.el-table__row:not(:last-child) {
  border-bottom: 1px solid #f1f5f9;
}

/* 优化表格内容展示 */
.el-table .cell {
  white-space: normal;
  word-break: break-word;
}

/* 分页控件优化 */
.el-pagination {
  margin-top: 20px;
  padding: 16px 20px;
  background: #f8fafc;
  border-top: 1px solid #e2e8f0;
}

.el-pagination.is-background .el-pager li:not(.disabled).active {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-color: transparent;
}

.el-pagination.is-background .el-pager li:hover:not(.disabled) {
  color: #667eea;
}

/* 优化按钮样式 */
.el-button--primary.el-button--small {
  background: #667eea;
  border: none;
  border-radius: 6px;
  transition: all 0.2s ease;
}

.el-button--primary.el-button--small:hover {
  background: #764ba2;
}

.el-button--danger.el-button--small {
  background: #ef4444;
  border: none;
  border-radius: 6px;
  transition: all 0.2s ease;
}

.el-button--danger.el-button--small:hover {
  background: #dc2626;
}

/* 优化徽章样式 */
.el-badge__content {
  border-radius: 12px;
  padding: 0 8px;
}

/* 修复建议样式优化 */
.vulnerability-count {
  font-weight: 600;
  color: #ef4444;
  font-size: 16px;
}

.task-id {
  font-family: 'Courier New', monospace;
  color: #64748b;
  font-weight: 500;
}

/* 动画效果 */
@keyframes countUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 全局容器优化 */
.dashboard-container {
  padding: 20px;
  min-height: 100vh;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
}

/* 卡片通用样式 */
.card {
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
  border: 1px solid #e2e8f0;
  background: white;
  margin-bottom: 24px;
  transition: all 0.3s ease;
}

.card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
}

.card-header {
  padding: 18px 24px;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
  border-bottom: 1px solid #e2e8f0;
}

.card-content {
  padding: 20px 24px;
}

/* 优化按钮通用样式 */
.el-button {
  border-radius: 8px;
  transition: all 0.3s ease;
  font-weight: 500;
}

.el-button:hover {
  transform: translateY(-1px);
}

.el-button--primary {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
}

.el-button--primary:hover {
  background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
}

/* 优化徽章样式 */
.el-tag {
  border-radius: 20px;
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 500;
}

/* 优化metric-item样式 */
.metric-item {
  display: flex;
  align-items: center;
  margin-bottom: 6px;
  padding: 4px 0;
}

.metric-item .metric-label {
  font-size: 13px;
  color: #64748b;
  margin-right: 8px;
  font-weight: 500;
  min-width: 55px;
}

.metric-item .metric-value {
  font-size: 13px;
  color: #1e293b;
  font-weight: 600;
}

/* 平滑滚动 */
html {
  scroll-behavior: smooth;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .dashboard-container {
    padding: 12px;
  }
  
  .top-toolbar {
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
  }
  
  .toolbar-left,
  .toolbar-right {
    justify-content: center;
  }
  
  .overview-metrics {
    flex-direction: column;
    gap: 12px;
  }
  
  .overview-metric {
    min-width: auto;
    padding: 12px;
  }
  
  .overview-trend-chart {
    height: 250px;
    padding: 0 16px 16px;
  }
  
  .metrics-grid {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  
  .card-header,
  .card-content {
    padding: 16px;
  }
  
  .el-table th,
  .el-table td {
    padding: 12px 8px;
    font-size: 13px;
  }
}
</style>